mirror of
https://git.plasmaofthedawn.com/adventofcode.git
synced 2025-12-23 18:17:35 -06:00
initial commit
This commit is contained in:
53
src/pascal/2023/day1/part1.pas
Normal file
53
src/pascal/2023/day1/part1.pas
Normal file
@@ -0,0 +1,53 @@
|
||||
program day1part1;
|
||||
|
||||
var
|
||||
file_: text;
|
||||
start: string;
|
||||
c: char;
|
||||
first, last: char;
|
||||
sum, value: int32;
|
||||
|
||||
(* Here the main program block starts *)
|
||||
begin
|
||||
{ open inp.txt for reading }
|
||||
assign(file_, 'resources/2023/day1.txt');
|
||||
reset(file_);
|
||||
|
||||
{ initialize sum to 0 }
|
||||
sum := 0;
|
||||
|
||||
{ until the file is empty }
|
||||
while not eof(file_) do
|
||||
begin
|
||||
|
||||
{ read a line from the file }
|
||||
readln(file_, start);
|
||||
|
||||
{ fill in placeholders }
|
||||
first := 'a';
|
||||
last := 'a';
|
||||
|
||||
{ for each characters }
|
||||
for c in start do
|
||||
begin
|
||||
{ if it is a number }
|
||||
if (('0' <= c) and (c <= '9')) then
|
||||
begin
|
||||
{ set last to that number }
|
||||
last := c;
|
||||
{ if first hasn't been set, then set it as a number}
|
||||
if (first = 'a') then
|
||||
first := c
|
||||
end;
|
||||
end;
|
||||
|
||||
{ calculate the actual value of the number and add it to the sum }
|
||||
val(concat(first, last), value);
|
||||
sum := sum + value;
|
||||
|
||||
end;
|
||||
|
||||
{ print out that beautiful sum}
|
||||
writeln(sum);
|
||||
|
||||
end.
|
||||
75
src/pascal/2023/day1/part2.pas
Normal file
75
src/pascal/2023/day1/part2.pas
Normal file
@@ -0,0 +1,75 @@
|
||||
program day2part2;
|
||||
uses sysutils;
|
||||
|
||||
var
|
||||
file_: text;
|
||||
start: string;
|
||||
c: char;
|
||||
first, last: char;
|
||||
value, sum: int32;
|
||||
names: array [0..9] of string = ('zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine');
|
||||
numbers: array [0..9] of char = ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9');
|
||||
i, j: int32;
|
||||
s: string;
|
||||
|
||||
(* Here the main program block starts *)
|
||||
begin
|
||||
|
||||
{ open inp.txt for reading }
|
||||
assign(file_, 'resources/2023/day1.txt');
|
||||
reset(file_);
|
||||
|
||||
{ initialize sum to 0 }
|
||||
sum := 0;
|
||||
|
||||
{ until the file is empty }
|
||||
while not eof(file_) do
|
||||
begin
|
||||
|
||||
{ read a line from the file }
|
||||
readln(file_, start);
|
||||
|
||||
{ fill in placeholders }
|
||||
first := 'a';
|
||||
last := 'a';
|
||||
|
||||
{ for each characters }
|
||||
for i := 1 to length(start) do
|
||||
begin
|
||||
|
||||
c := start[i];
|
||||
|
||||
{ check for text number }
|
||||
for j := 0 to 9 do
|
||||
begin
|
||||
{ compare the substring with the name of a number }
|
||||
s := copy(start, i, length(names[j]));
|
||||
if (comparestr(s, names[j]) = 0) then
|
||||
begin
|
||||
{ if it matches then this is a number }
|
||||
c := numbers[j];
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ if it is a number }
|
||||
if (('0' <= c) and (c <= '9')) then
|
||||
begin
|
||||
{ set last to that number }
|
||||
last := c;
|
||||
{ if first hasn't been set, then set it as a number}
|
||||
if (first = 'a') then
|
||||
first := c
|
||||
end;
|
||||
end;
|
||||
|
||||
{ calculate the actual value of the number and add it to the sum }
|
||||
val(first + last, value);
|
||||
sum := sum + value;
|
||||
|
||||
end;
|
||||
|
||||
{ print out that beautiful sum }
|
||||
writeln(sum);
|
||||
|
||||
end.
|
||||
136
src/pascal/2023/day10/part1.pas
Normal file
136
src/pascal/2023/day10/part1.pas
Normal file
@@ -0,0 +1,136 @@
|
||||
program day10part1;
|
||||
uses sysutils;
|
||||
|
||||
type
|
||||
direction = (Left, Up, Right, Down, NA);
|
||||
|
||||
|
||||
function step_path(var curr: array of int32; last_direction: direction; c: char): direction;
|
||||
begin
|
||||
|
||||
// step_path := curr;
|
||||
|
||||
step_path := NA;
|
||||
|
||||
case last_direction of
|
||||
Left:
|
||||
begin
|
||||
case c of
|
||||
'-': step_path := Left;
|
||||
'L': step_path := Up;
|
||||
'F': step_path := Down;
|
||||
end;
|
||||
end;
|
||||
Up:
|
||||
begin
|
||||
case c of
|
||||
'|': step_path := Up;
|
||||
'7': step_path := Left;
|
||||
'F': step_path := Right;
|
||||
end;
|
||||
end;
|
||||
Right:
|
||||
begin
|
||||
case c of
|
||||
'-': step_path := Right;
|
||||
'7': step_path := Down;
|
||||
'J': step_path := Up;
|
||||
end;
|
||||
end;
|
||||
Down:
|
||||
begin
|
||||
case c of
|
||||
'|': step_path := Down;
|
||||
'J': step_path := Left;
|
||||
'L': step_path := Right;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
case step_path of
|
||||
Up: curr[0] := curr[0] - 1;
|
||||
Down: curr[0] := curr[0] + 1;
|
||||
Left: curr[1] := curr[1] - 1;
|
||||
Right: curr[1] := curr[1] + 1;
|
||||
end;
|
||||
|
||||
if (last_direction = NA) then
|
||||
writeln('bruh');
|
||||
|
||||
end;
|
||||
|
||||
var
|
||||
file_: text;
|
||||
|
||||
map: array[1..1000] of string;
|
||||
str: string;
|
||||
|
||||
count: int32;
|
||||
|
||||
steps: int32;
|
||||
step: char;
|
||||
|
||||
s_loc, loc: array[0..1] of int32;
|
||||
ld: direction;
|
||||
|
||||
i: int32;
|
||||
|
||||
{ node, left, right }
|
||||
nodes: array[0..1000, 0..2] of string;
|
||||
|
||||
begin
|
||||
{ open inp.txt for reading }
|
||||
assign(file_, 'resources/2023/day10.txt');
|
||||
reset(file_);
|
||||
|
||||
count := 1;
|
||||
while not EOF(file_) do
|
||||
begin
|
||||
|
||||
readln(file_, map[count]);
|
||||
|
||||
i := pos('S', map[count]);
|
||||
|
||||
if i <> 0 then
|
||||
begin
|
||||
s_loc[0] := count;
|
||||
s_loc[1] := i;
|
||||
end;
|
||||
|
||||
count := count + 1;
|
||||
|
||||
end;
|
||||
|
||||
loc := s_loc;
|
||||
count := 0;
|
||||
|
||||
{ get possible initial directions }
|
||||
if (map[s_loc[0], s_loc[1] - 1] = '-') or (map[s_loc[0], s_loc[1] - 1] = 'F') or (map[s_loc[0], s_loc[1] - 1] = 'L') then
|
||||
begin
|
||||
loc[1] := loc[1] - 1;
|
||||
ld := Left;
|
||||
end
|
||||
else if (map[s_loc[0] - 1, s_loc[1]] = '|') or (map[s_loc[0] - 1, s_loc[1]] = '7') or (map[s_loc[0] - 1, s_loc[1]] = 'F') then
|
||||
begin
|
||||
loc[0] := loc[0] - 1;
|
||||
ld := Up;
|
||||
end
|
||||
else
|
||||
begin
|
||||
{ if it's neither up nor left, then both right and down must be valid. }
|
||||
{ pick right arbitrarily }
|
||||
ld := Right;
|
||||
loc[1] := loc[1] + 1;
|
||||
end;
|
||||
|
||||
while (loc[0] <> s_loc[0]) or (loc[1] <> s_loc[1]) do
|
||||
begin
|
||||
count := count + 1;
|
||||
ld := step_path(loc, ld, map[loc[0], loc[1]]);
|
||||
end;
|
||||
|
||||
count := count + 1;
|
||||
writeln(count div 2);
|
||||
|
||||
end.
|
||||
|
||||
276
src/pascal/2023/day10/part2.pas
Normal file
276
src/pascal/2023/day10/part2.pas
Normal file
@@ -0,0 +1,276 @@
|
||||
program day10part1;
|
||||
uses sysutils;
|
||||
|
||||
type
|
||||
direction = (Left, Up, Right, Down, NA);
|
||||
blocktype = (Empty, Pipe, Red, Blue);
|
||||
|
||||
var
|
||||
blocks: array[1..1000, 1..1000] of blocktype;
|
||||
|
||||
|
||||
procedure replace_if_not_pipe(y: int32; x: int32; new_type: blocktype);
|
||||
begin
|
||||
if blocks[y, x] <> Pipe then
|
||||
blocks[y, x] := new_type
|
||||
end;
|
||||
|
||||
function step_path(var curr: array of int32; last_direction: direction; c: char): direction;
|
||||
begin
|
||||
|
||||
// step_path := curr;
|
||||
|
||||
step_path := NA;
|
||||
|
||||
{ mark lefthand side as blue, righthand side as red }
|
||||
case last_direction of
|
||||
Left:
|
||||
begin
|
||||
replace_if_not_pipe(curr[0] - 1, curr[1], Red);
|
||||
replace_if_not_pipe(curr[0] + 1, curr[1], Blue);
|
||||
end;
|
||||
Right:
|
||||
begin
|
||||
replace_if_not_pipe(curr[0] - 1, curr[1], Blue);
|
||||
replace_if_not_pipe(curr[0] + 1, curr[1], Red);
|
||||
end;
|
||||
Down:
|
||||
begin
|
||||
replace_if_not_pipe(curr[0], curr[1] - 1, Red);
|
||||
replace_if_not_pipe(curr[0], curr[1] + 1, Blue);
|
||||
end;
|
||||
Up:
|
||||
begin
|
||||
replace_if_not_pipe(curr[0], curr[1] - 1, Blue);
|
||||
replace_if_not_pipe(curr[0], curr[1] + 1, Red);
|
||||
end;
|
||||
end;
|
||||
|
||||
case last_direction of
|
||||
Left:
|
||||
begin
|
||||
case c of
|
||||
'-': step_path := Left;
|
||||
'L': step_path := Up;
|
||||
'F': step_path := Down;
|
||||
end;
|
||||
end;
|
||||
Up:
|
||||
begin
|
||||
case c of
|
||||
'|': step_path := Up;
|
||||
'7': step_path := Left;
|
||||
'F': step_path := Right;
|
||||
end;
|
||||
end;
|
||||
Right:
|
||||
begin
|
||||
case c of
|
||||
'-': step_path := Right;
|
||||
'7': step_path := Down;
|
||||
'J': step_path := Up;
|
||||
end;
|
||||
end;
|
||||
Down:
|
||||
begin
|
||||
case c of
|
||||
'|': step_path := Down;
|
||||
'J': step_path := Left;
|
||||
'L': step_path := Right;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ mark lefthand side as blue, righthand side as red }
|
||||
case step_path of
|
||||
Left:
|
||||
begin
|
||||
replace_if_not_pipe(curr[0] - 1, curr[1], Red);
|
||||
replace_if_not_pipe(curr[0] + 1, curr[1], Blue);
|
||||
end;
|
||||
Right:
|
||||
begin
|
||||
replace_if_not_pipe(curr[0] - 1, curr[1], Blue);
|
||||
replace_if_not_pipe(curr[0] + 1, curr[1], Red);
|
||||
end;
|
||||
Down:
|
||||
begin
|
||||
replace_if_not_pipe(curr[0], curr[1] - 1, Red);
|
||||
replace_if_not_pipe(curr[0], curr[1] + 1, Blue);
|
||||
end;
|
||||
Up:
|
||||
begin
|
||||
replace_if_not_pipe(curr[0], curr[1] - 1, Blue);
|
||||
replace_if_not_pipe(curr[0], curr[1] + 1, Red);
|
||||
end;
|
||||
end;
|
||||
|
||||
{ move to the next pipe }
|
||||
case step_path of
|
||||
Up: curr[0] := curr[0] - 1;
|
||||
Down: curr[0] := curr[0] + 1;
|
||||
Left: curr[1] := curr[1] - 1;
|
||||
Right: curr[1] := curr[1] + 1;
|
||||
end;
|
||||
|
||||
if (last_direction = NA) then
|
||||
writeln('bruh');
|
||||
|
||||
end;
|
||||
|
||||
var
|
||||
file_: text;
|
||||
|
||||
map: array[1..1000] of string;
|
||||
str: string;
|
||||
|
||||
count: int32;
|
||||
|
||||
width: int32;
|
||||
|
||||
steps: int32;
|
||||
step: char;
|
||||
|
||||
s_loc, loc: array[0..1] of int32;
|
||||
ld: direction;
|
||||
|
||||
i, j: int32;
|
||||
|
||||
{ node, left, right }
|
||||
nodes: array[0..1000, 0..2] of string;
|
||||
|
||||
current: blocktype;
|
||||
invalid: blocktype;
|
||||
|
||||
red_count, blue_count: int32;
|
||||
|
||||
begin
|
||||
{ open inp.txt for reading }
|
||||
assign(file_, 'resources/2023/day10.txt');
|
||||
reset(file_);
|
||||
|
||||
count := 1;
|
||||
while not EOF(file_) do
|
||||
begin
|
||||
|
||||
readln(file_, map[count]);
|
||||
|
||||
i := pos('S', map[count]);
|
||||
|
||||
if i <> 0 then
|
||||
begin
|
||||
s_loc[0] := count;
|
||||
s_loc[1] := i;
|
||||
end;
|
||||
|
||||
count := count + 1;
|
||||
|
||||
end;
|
||||
|
||||
width := length(map[1]);
|
||||
|
||||
loc := s_loc;
|
||||
|
||||
{ get possible initial directions }
|
||||
if (map[s_loc[0], s_loc[1] - 1] = '-') or (map[s_loc[0], s_loc[1] - 1] = 'F') or (map[s_loc[0], s_loc[1] - 1] = 'L') then
|
||||
begin
|
||||
loc[1] := loc[1] - 1;
|
||||
ld := Left;
|
||||
end
|
||||
else if (map[s_loc[0] - 1, s_loc[1]] = '|') or (map[s_loc[0] - 1, s_loc[1]] = '7') or (map[s_loc[0] - 1, s_loc[1]] = 'F') then
|
||||
begin
|
||||
loc[0] := loc[0] - 1;
|
||||
ld := Up;
|
||||
end
|
||||
else
|
||||
begin
|
||||
{ if it's neither up nor left, then both right and down must be valid. }
|
||||
{ pick right arbitrarily }
|
||||
ld := Right;
|
||||
loc[1] := loc[1] + 1;
|
||||
end;
|
||||
|
||||
// shitty memset
|
||||
for i := 1 to count do
|
||||
begin
|
||||
for j := 1 to width do
|
||||
begin
|
||||
blocks[i, j] := Empty;
|
||||
end;
|
||||
end;
|
||||
|
||||
blocks[s_loc[0], s_loc[1]] := Pipe;
|
||||
|
||||
|
||||
{ mark array of pipes, and set some red and blue squares }
|
||||
while (loc[0] <> s_loc[0]) or (loc[1] <> s_loc[1]) do
|
||||
begin
|
||||
|
||||
{ mark pipe }
|
||||
blocks[loc[0], loc[1]] := Pipe;
|
||||
|
||||
ld := step_path(loc, ld, map[loc[0], loc[1]]);
|
||||
end;
|
||||
{ step one additional time }
|
||||
ld := step_path(loc, ld, map[loc[0], loc[1]]);
|
||||
|
||||
{ fill in the map and count}
|
||||
{ techincally filling in the map is uneccessary but it looks cool }
|
||||
|
||||
red_count := 0;
|
||||
blue_count := 0;
|
||||
|
||||
for i := 1 to count - 1 do
|
||||
begin
|
||||
current := Empty;
|
||||
for j := 1 to width do
|
||||
begin
|
||||
case blocks[i, j] of
|
||||
Empty:
|
||||
begin
|
||||
blocks[i, j] := current;
|
||||
case current of
|
||||
Red: red_count := red_count + 1;
|
||||
Blue: blue_count := blue_count + 1;
|
||||
end;
|
||||
end;
|
||||
// Pipe you do nothing
|
||||
Red:
|
||||
begin
|
||||
current := Red;
|
||||
red_count := red_count + 1;
|
||||
end;
|
||||
Blue:
|
||||
begin
|
||||
current := Blue;
|
||||
blue_count := blue_count + 1;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ if we're holding onto this at the end, then this is the color outside of the square}
|
||||
if current <> Empty then
|
||||
invalid := current
|
||||
end;
|
||||
|
||||
{ print out the map }
|
||||
for i := 1 to count - 1 do
|
||||
begin
|
||||
for j := 1 to width do
|
||||
begin
|
||||
case blocks[i, j] of
|
||||
Empty: write(' ');
|
||||
Pipe: write('█');
|
||||
Red: write('▒');
|
||||
Blue: write('░');
|
||||
end;
|
||||
end;
|
||||
writeln();
|
||||
end;
|
||||
|
||||
writeln(invalid, ' is bad color.');
|
||||
writeln('Red count is ', red_count);
|
||||
writeln('Blue count is ', blue_count);
|
||||
|
||||
end.
|
||||
|
||||
113
src/pascal/2023/day11/part1.pas
Normal file
113
src/pascal/2023/day11/part1.pas
Normal file
@@ -0,0 +1,113 @@
|
||||
program day11part1;
|
||||
uses sysutils;
|
||||
|
||||
|
||||
function dist_between(x1, x2: int32; empty_list: array of boolean): int32;
|
||||
var
|
||||
i: int32;
|
||||
begin
|
||||
|
||||
{ swap operands so x1 is always smaller}
|
||||
if (x2 < x1) then
|
||||
begin
|
||||
i := x2;
|
||||
x2 := x1;
|
||||
x1 := i;
|
||||
end;
|
||||
|
||||
{ calculate distance }
|
||||
dist_between := 0;
|
||||
for i := x1 to x2 - 1 do
|
||||
begin
|
||||
|
||||
dist_between := dist_between + 1;
|
||||
|
||||
{ if gap, increment by an additional 1 }
|
||||
if empty_list[i] then
|
||||
dist_between := dist_between + 1;
|
||||
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
function galaxy_dist(g1, g2: array of int64; row_list, col_list: array of boolean): int32;
|
||||
begin
|
||||
galaxy_dist := dist_between(g1[0], g2[0], col_list) + dist_between(g1[1], g2[1], row_list);
|
||||
end;
|
||||
|
||||
var
|
||||
file_: text;
|
||||
|
||||
str: string;
|
||||
|
||||
galaxies: array[0..1000, 0..1] of int64;
|
||||
galaxy_count: int32;
|
||||
|
||||
column_empty: array[1..1000] of boolean;
|
||||
row_empty: array[1..1000] of boolean;
|
||||
|
||||
i, j: int32;
|
||||
count: int32;
|
||||
|
||||
sum: int32;
|
||||
|
||||
begin
|
||||
{ open inp.txt for reading }
|
||||
assign(file_, 'resources/2023/day11.txt');
|
||||
reset(file_);
|
||||
|
||||
{ set row/cols to empty }
|
||||
for i := 0 to 1000 do
|
||||
begin
|
||||
column_empty[i] := true;
|
||||
row_empty[i] := true;
|
||||
end;
|
||||
|
||||
count := 0;
|
||||
galaxy_count := 0;
|
||||
|
||||
{ read file }
|
||||
while not EOF(file_) do
|
||||
begin
|
||||
|
||||
count := count + 1;
|
||||
|
||||
readln(file_, str);
|
||||
|
||||
for i := 1 to length(str) do
|
||||
begin
|
||||
|
||||
if str[i] = '#' then
|
||||
begin
|
||||
|
||||
{ record this galaxy }
|
||||
galaxy_count := galaxy_count + 1;
|
||||
|
||||
galaxies[galaxy_count][0] := i;
|
||||
galaxies[galaxy_count][1] := count;
|
||||
|
||||
{ mark rows/cols as nonempty }
|
||||
row_empty[count] := false;
|
||||
column_empty[i] := false;
|
||||
|
||||
end;
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
sum := 0;
|
||||
{ for each pair }
|
||||
for i := 1 to galaxy_count do
|
||||
begin
|
||||
for j := i + 1 to galaxy_count do
|
||||
begin
|
||||
|
||||
{ sum the pairwise distance }
|
||||
sum := sum + galaxy_dist(galaxies[i], galaxies[j], row_empty, column_empty);
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
writeln('The sum is ', sum);
|
||||
end.
|
||||
|
||||
113
src/pascal/2023/day11/part2.pas
Normal file
113
src/pascal/2023/day11/part2.pas
Normal file
@@ -0,0 +1,113 @@
|
||||
program day11part1;
|
||||
uses sysutils;
|
||||
|
||||
|
||||
function dist_between(x1, x2: int32; empty_list: array of boolean): int64;
|
||||
var
|
||||
i: int32;
|
||||
begin
|
||||
|
||||
{ swap operands so x1 is always smaller}
|
||||
if (x2 < x1) then
|
||||
begin
|
||||
i := x2;
|
||||
x2 := x1;
|
||||
x1 := i;
|
||||
end;
|
||||
|
||||
{ calculate distance }
|
||||
dist_between := 0;
|
||||
for i := x1 to x2 - 1 do
|
||||
begin
|
||||
|
||||
dist_between := dist_between + 1;
|
||||
|
||||
{ if gap, increment by an additional 999999 }
|
||||
if empty_list[i] then
|
||||
dist_between := dist_between + 999999;
|
||||
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
function galaxy_dist(g1, g2: array of int64; row_list, col_list: array of boolean): int64;
|
||||
begin
|
||||
galaxy_dist := dist_between(g1[0], g2[0], col_list) + dist_between(g1[1], g2[1], row_list);
|
||||
end;
|
||||
|
||||
var
|
||||
file_: text;
|
||||
|
||||
str: string;
|
||||
|
||||
galaxies: array[0..1000, 0..1] of int64;
|
||||
galaxy_count: int32;
|
||||
|
||||
column_empty: array[1..1000] of boolean;
|
||||
row_empty: array[1..1000] of boolean;
|
||||
|
||||
i, j: int32;
|
||||
count: int32;
|
||||
|
||||
sum: int64;
|
||||
|
||||
begin
|
||||
{ open inp.txt for reading }
|
||||
assign(file_, 'resources/2023/day11.txt');
|
||||
reset(file_);
|
||||
|
||||
{ set row/cols to empty }
|
||||
for i := 0 to 1000 do
|
||||
begin
|
||||
column_empty[i] := true;
|
||||
row_empty[i] := true;
|
||||
end;
|
||||
|
||||
count := 0;
|
||||
galaxy_count := 0;
|
||||
|
||||
{ read file }
|
||||
while not EOF(file_) do
|
||||
begin
|
||||
|
||||
count := count + 1;
|
||||
|
||||
readln(file_, str);
|
||||
|
||||
for i := 1 to length(str) do
|
||||
begin
|
||||
|
||||
if str[i] = '#' then
|
||||
begin
|
||||
|
||||
{ record this galaxy }
|
||||
galaxy_count := galaxy_count + 1;
|
||||
|
||||
galaxies[galaxy_count][0] := i;
|
||||
galaxies[galaxy_count][1] := count;
|
||||
|
||||
{ mark rows/cols as nonempty }
|
||||
row_empty[count] := false;
|
||||
column_empty[i] := false;
|
||||
|
||||
end;
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
sum := 0;
|
||||
{ for each pair }
|
||||
for i := 1 to galaxy_count do
|
||||
begin
|
||||
for j := i + 1 to galaxy_count do
|
||||
begin
|
||||
|
||||
{ sum the pairwise distance }
|
||||
sum := sum + galaxy_dist(galaxies[i], galaxies[j], row_empty, column_empty);
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
writeln('The sum is ', sum);
|
||||
end.
|
||||
|
||||
205
src/pascal/2023/day12/part1.pas
Normal file
205
src/pascal/2023/day12/part1.pas
Normal file
@@ -0,0 +1,205 @@
|
||||
{$mode objfpc}
|
||||
|
||||
program day12part1;
|
||||
uses sysutils;
|
||||
|
||||
type
|
||||
int32array = array of int32;
|
||||
stringarray = array of string;
|
||||
|
||||
function sum(l: array of int32; start: int32 = 0): int32;
|
||||
var
|
||||
i: int32;
|
||||
begin
|
||||
sum := 0;
|
||||
for i := start to length(l) - 1 do
|
||||
sum := l[i] + sum;
|
||||
end;
|
||||
|
||||
function split_to_int(s: string; delim: char): int32array ;
|
||||
var
|
||||
i, last_delim, count : int32;
|
||||
c: char;
|
||||
begin
|
||||
|
||||
{ there will always be at least one number }
|
||||
count := 1;
|
||||
{ count number of delimeters }
|
||||
for c in s do
|
||||
begin
|
||||
if c = delim then
|
||||
count := count + 1;
|
||||
end;
|
||||
|
||||
{ allocate enough space for count}
|
||||
setlength(split_to_int, count);
|
||||
|
||||
count := 0;
|
||||
last_delim := 0;
|
||||
|
||||
{ second interation }
|
||||
for i := 1 to length(s) do
|
||||
begin
|
||||
{ if this is a delimeter }
|
||||
if s[i] = delim then
|
||||
begin
|
||||
{ add the value between this delimiter and the previous one to splitted }
|
||||
val(
|
||||
copy(s, last_delim + 1, i - last_delim - 1), split_to_int[count]
|
||||
);
|
||||
count := count + 1;
|
||||
last_delim := i;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ don't forget the final value }
|
||||
val(
|
||||
copy(s, last_delim + 1, length(s) - last_delim), split_to_int[count]
|
||||
);
|
||||
end;
|
||||
|
||||
function split_to_str(s: string; delim: char): stringarray;
|
||||
var
|
||||
i, last_delim, count : int32;
|
||||
c: char;
|
||||
begin
|
||||
|
||||
{ there will always be at least one number }
|
||||
count := 1;
|
||||
{ count number of delimeters }
|
||||
for c in s do
|
||||
begin
|
||||
if c = delim then
|
||||
count := count + 1;
|
||||
end;
|
||||
|
||||
{ allocate enough space for count}
|
||||
setlength(split_to_str, count);
|
||||
|
||||
count := 0;
|
||||
last_delim := 0;
|
||||
|
||||
{ second interation }
|
||||
for i := 1 to length(s) do
|
||||
begin
|
||||
{ if this is a delimeter }
|
||||
if s[i] = delim then
|
||||
begin
|
||||
{ add the value between this delimiter and the previous one to splitted }
|
||||
split_to_str[count] := copy(s, last_delim + 1, i - last_delim - 1);
|
||||
count := count + 1;
|
||||
last_delim := i;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ don't forget the final value }
|
||||
split_to_str[count] := copy(s, last_delim + 1, length(s) - last_delim)
|
||||
end;
|
||||
|
||||
function will_fit(s: string; idx, length: int32): boolean;
|
||||
var
|
||||
i: int32;
|
||||
begin
|
||||
will_fit := true;
|
||||
for i := idx to idx + length - 1 do
|
||||
begin
|
||||
if s[i] = '.' then
|
||||
begin
|
||||
will_fit := false;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function all_after_not(s: string; idx: int32; c: char): boolean;
|
||||
var
|
||||
i: int32;
|
||||
begin
|
||||
all_after_not := true;
|
||||
for i := idx to length(s) do
|
||||
begin
|
||||
if s[i] = c then
|
||||
begin
|
||||
all_after_not := false;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function possibilties(s: string; l: array of int32; start_s: int32 = 1; start_l: int32 = 0): int32;
|
||||
var
|
||||
i: int32;
|
||||
|
||||
begin
|
||||
|
||||
possibilties := 0;
|
||||
|
||||
// writeln(s, l[start_l], length(l), start_s, start_l);
|
||||
|
||||
{ if there is only one spring left then }
|
||||
if length(l) - start_l = 1 then
|
||||
begin
|
||||
|
||||
{ check every possibility }
|
||||
for i := start_s to length(s) - l[start_l] + 1 do
|
||||
begin
|
||||
{ if it will fit here, then it's valid }
|
||||
if will_fit(s, i, l[start_l]) and all_after_not(s, i + l[start_l], '#') then
|
||||
possibilties := possibilties + 1;
|
||||
|
||||
{ if we pass by a #, then it's not valid anymore as the # won't be filled }
|
||||
if s[i] = '#' then
|
||||
break;
|
||||
end;
|
||||
|
||||
end
|
||||
else
|
||||
begin
|
||||
|
||||
for i := start_s to length(s) - sum(l, start_l) - length(l) + start_l + 2 do
|
||||
begin
|
||||
{ if it will fit and we aren't skipping a '#', recursively find possibilities }
|
||||
|
||||
if will_fit(s, i, l[start_l]) and (s[i + l[start_l]] <> '#') then
|
||||
possibilties := possibilties + possibilties(s, l, i + l[start_l] + 1, start_l + 1);
|
||||
|
||||
{ if we pass by a #, then it's not valid anymore as the # won't be filled }
|
||||
if s[i] = '#' then
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
var
|
||||
|
||||
s: string;
|
||||
pattern: array of int32;
|
||||
|
||||
split: array of string;
|
||||
|
||||
file_: text;
|
||||
|
||||
total: int32;
|
||||
|
||||
begin
|
||||
|
||||
assign(file_, 'resources/2023/day12.txt');
|
||||
reset(file_);
|
||||
|
||||
total := 0;
|
||||
|
||||
while not EOF(file_) do
|
||||
begin
|
||||
|
||||
readln(file_, s);
|
||||
split := split_to_str(s, ' ');
|
||||
|
||||
pattern := split_to_int(split[1], ',');
|
||||
|
||||
total := total + possibilties(split[0], pattern);
|
||||
|
||||
end;
|
||||
|
||||
writeln('The sum is ', total);
|
||||
end.
|
||||
|
||||
250
src/pascal/2023/day12/part2.pas
Normal file
250
src/pascal/2023/day12/part2.pas
Normal file
@@ -0,0 +1,250 @@
|
||||
{$mode objfpc}
|
||||
{$RANGECHECKS ON}
|
||||
|
||||
program day12part1;
|
||||
uses sysutils;
|
||||
|
||||
type
|
||||
int64array = array of int64;
|
||||
stringarray = array of string;
|
||||
|
||||
function sum(l: array of int64; start: int64 = 0): int64;
|
||||
var
|
||||
i: int64;
|
||||
begin
|
||||
sum := 0;
|
||||
for i := start to length(l) - 1 do
|
||||
sum := l[i] + sum;
|
||||
end;
|
||||
|
||||
function split_to_int(s: string; delim: char): int64array ;
|
||||
var
|
||||
i, last_delim, count : int64;
|
||||
c: char;
|
||||
begin
|
||||
|
||||
{ there will always be at least one number }
|
||||
count := 1;
|
||||
{ count number of delimeters }
|
||||
for c in s do
|
||||
begin
|
||||
if c = delim then
|
||||
count := count + 1;
|
||||
end;
|
||||
|
||||
{ allocate enough space for count}
|
||||
setlength(split_to_int, count);
|
||||
|
||||
count := 0;
|
||||
last_delim := 0;
|
||||
|
||||
{ second interation }
|
||||
for i := 1 to length(s) do
|
||||
begin
|
||||
{ if this is a delimeter }
|
||||
if s[i] = delim then
|
||||
begin
|
||||
{ add the value between this delimiter and the previous one to splitted }
|
||||
val(
|
||||
copy(s, last_delim + 1, i - last_delim - 1), split_to_int[count]
|
||||
);
|
||||
count := count + 1;
|
||||
last_delim := i;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ don't forget the final value }
|
||||
val(
|
||||
copy(s, last_delim + 1, length(s) - last_delim), split_to_int[count]
|
||||
);
|
||||
end;
|
||||
|
||||
function split_to_str(s: string; delim: char): stringarray;
|
||||
var
|
||||
i, last_delim, count : int64;
|
||||
c: char;
|
||||
begin
|
||||
|
||||
{ there will always be at least one number }
|
||||
count := 1;
|
||||
{ count number of delimeters }
|
||||
for c in s do
|
||||
begin
|
||||
if c = delim then
|
||||
count := count + 1;
|
||||
end;
|
||||
|
||||
{ allocate enough space for count}
|
||||
setlength(split_to_str, count);
|
||||
|
||||
count := 0;
|
||||
last_delim := 0;
|
||||
|
||||
{ second interation }
|
||||
for i := 1 to length(s) do
|
||||
begin
|
||||
{ if this is a delimeter }
|
||||
if s[i] = delim then
|
||||
begin
|
||||
{ add the value between this delimiter and the previous one to splitted }
|
||||
split_to_str[count] := copy(s, last_delim + 1, i - last_delim - 1);
|
||||
count := count + 1;
|
||||
last_delim := i;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ don't forget the final value }
|
||||
split_to_str[count] := copy(s, last_delim + 1, length(s) - last_delim)
|
||||
end;
|
||||
|
||||
function will_fit(s: string; idx, length: int64): boolean;
|
||||
var
|
||||
i: int64;
|
||||
begin
|
||||
will_fit := true;
|
||||
for i := idx to idx + length - 1 do
|
||||
begin
|
||||
if s[i] = '.' then
|
||||
begin
|
||||
will_fit := false;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function all_after_not(s: string; idx: int64; c: char): boolean;
|
||||
var
|
||||
i: int64;
|
||||
begin
|
||||
all_after_not := true;
|
||||
for i := idx to length(s) do
|
||||
begin
|
||||
if s[i] = c then
|
||||
begin
|
||||
all_after_not := false;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
var
|
||||
cache: array[0..1000, 0..1000] of int64;
|
||||
|
||||
procedure clear_cache();
|
||||
var
|
||||
i, j: int64;
|
||||
begin
|
||||
for i := 0 to 1000 do
|
||||
begin
|
||||
for j:= 0 to 1000 do
|
||||
begin
|
||||
cache[i, j] := -1;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function possibilties(s: string; l: array of int64; start_s: int64 = 1; start_l: int64 = 0): int64;
|
||||
var
|
||||
i: int64;
|
||||
|
||||
begin
|
||||
|
||||
possibilties := 0;
|
||||
|
||||
{ clear the cache if we r starting }
|
||||
if start_l = 0 then
|
||||
clear_cache();
|
||||
|
||||
{ return cache if we have the value }
|
||||
if cache[start_s, start_l] <> -1 then
|
||||
begin
|
||||
possibilties := cache[start_s, start_l];
|
||||
exit;
|
||||
end;
|
||||
|
||||
{ if there is only one spring left then }
|
||||
if length(l) - start_l = 1 then
|
||||
begin
|
||||
|
||||
{ check every possibility }
|
||||
for i := start_s to length(s) - l[start_l] + 1 do
|
||||
begin
|
||||
{ if it will fit here, then it's valid }
|
||||
if will_fit(s, i, l[start_l]) and all_after_not(s, i + l[start_l], '#') then
|
||||
possibilties := possibilties + 1;
|
||||
|
||||
{ if we pass by a #, then it's not valid anymore as the # won't be filled }
|
||||
if s[i] = '#' then
|
||||
break;
|
||||
end;
|
||||
|
||||
end
|
||||
else
|
||||
begin
|
||||
|
||||
for i := start_s to length(s) - sum(l, start_l) - length(l) + start_l + 2 do
|
||||
begin
|
||||
{ if it will fit and we aren't skipping a '#', recursively find possibilities }
|
||||
|
||||
if will_fit(s, i, l[start_l]) and (s[i + l[start_l]] <> '#') then
|
||||
possibilties := possibilties + possibilties(s, l, i + l[start_l] + 1, start_l + 1);
|
||||
|
||||
{ if we pass by a #, then it's not valid anymore as the # won't be filled }
|
||||
if s[i] = '#' then
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
|
||||
cache[start_s, start_l] := possibilties;
|
||||
|
||||
end;
|
||||
|
||||
function duplicate_int_array(arr: int64array; times: int64): int64array;
|
||||
var
|
||||
i: int64;
|
||||
begin
|
||||
setlength(duplicate_int_array, length(arr) * times);
|
||||
|
||||
for i := 0 to length(arr) * times - 1 do
|
||||
begin
|
||||
duplicate_int_array[i] := arr[i mod length(arr)];
|
||||
end;
|
||||
end;
|
||||
|
||||
var
|
||||
|
||||
s: string;
|
||||
pattern: array of int64;
|
||||
|
||||
split: array of string;
|
||||
|
||||
file_: text;
|
||||
|
||||
total: int64;
|
||||
|
||||
begin
|
||||
|
||||
assign(file_, 'resources/2023/day12.txt');
|
||||
reset(file_);
|
||||
|
||||
total := 0;
|
||||
|
||||
while not EOF(file_) do
|
||||
begin
|
||||
|
||||
readln(file_, s);
|
||||
split := split_to_str(s, ' ');
|
||||
|
||||
pattern := split_to_int(split[1], ',');
|
||||
|
||||
//total := total + possibilties(split[0], pattern);
|
||||
|
||||
total := total + possibilties(split[0] + '?' + split[0] + '?' + split[0] + '?' + split[0] + '?' + split[0],
|
||||
duplicate_int_array(pattern, 5));
|
||||
|
||||
|
||||
end;
|
||||
|
||||
writeln('The sum is ', total);
|
||||
end.
|
||||
|
||||
142
src/pascal/2023/day13/part1.pas
Normal file
142
src/pascal/2023/day13/part1.pas
Normal file
@@ -0,0 +1,142 @@
|
||||
{$mode objfpc}
|
||||
{$RANGECHECKS ON}
|
||||
|
||||
program day13part1;
|
||||
uses sysutils;
|
||||
|
||||
type
|
||||
Tmap = record
|
||||
map: array[1..100] of string;
|
||||
height: int32;
|
||||
width: int32;
|
||||
end;
|
||||
|
||||
function max(a, b: int32): int32;
|
||||
begin
|
||||
max := a;
|
||||
if b > a then
|
||||
max := b;
|
||||
end;
|
||||
|
||||
{ check for mirrors that lay vertically (column mirror) }
|
||||
function check_v_mirror(map: Tmap; col: int32): boolean;
|
||||
var
|
||||
i, j: int32;
|
||||
begin
|
||||
|
||||
check_v_mirror := true;
|
||||
for j := 1 to map.height do
|
||||
begin
|
||||
for i := max(1, 2 * col - map.width + 1) to col do
|
||||
begin
|
||||
// writeln(i, ' ', col*2 - i);
|
||||
if map.map[j, i] <> map.map[j, col * 2 - i + 1] then
|
||||
begin
|
||||
check_v_mirror := false;
|
||||
break
|
||||
end;
|
||||
end;
|
||||
|
||||
if not check_v_mirror then
|
||||
break;
|
||||
end;
|
||||
|
||||
check_v_mirror := check_v_mirror;
|
||||
|
||||
end;
|
||||
|
||||
{ check for mirrors that lay vertically (column mirror) }
|
||||
function check_h_mirror(map: Tmap; row: int32): boolean;
|
||||
var
|
||||
i, j: int32;
|
||||
begin
|
||||
|
||||
check_h_mirror := true;
|
||||
for j := 1 to map.width do
|
||||
begin
|
||||
for i := max(1, 2 * row - map.height + 1) to row do
|
||||
begin
|
||||
//writeln(i, ' ', row*2 - i + 1);
|
||||
if map.map[i, j] <> map.map[row * 2 - i + 1, j] then
|
||||
begin
|
||||
check_h_mirror := false;
|
||||
break
|
||||
end;
|
||||
end;
|
||||
|
||||
if not check_h_mirror then
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
function get_mirror(map: Tmap): int32;
|
||||
var
|
||||
i: int32;
|
||||
begin
|
||||
{ check vertical ones first }
|
||||
for i := 1 to map.width - 1 do
|
||||
begin
|
||||
if check_v_mirror(map, i) then
|
||||
begin
|
||||
get_mirror := i;
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ check horizontal ones now }
|
||||
for i := 1 to map.height - 1 do
|
||||
begin
|
||||
if check_h_mirror(map, i) then
|
||||
begin
|
||||
get_mirror := i shl 6 + i shl 5 + i shl 2;
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
var
|
||||
|
||||
map: Tmap;
|
||||
file_: text;
|
||||
s: string;
|
||||
total, map_count: int32;
|
||||
|
||||
begin
|
||||
|
||||
assign(file_, 'resources/2023/day13.txt');
|
||||
reset(file_);
|
||||
|
||||
total := 0;
|
||||
map_count := 0;
|
||||
|
||||
while not EOF(file_) do
|
||||
begin
|
||||
|
||||
readln(file_, s);
|
||||
writeln(s);
|
||||
if length(s) = 0 then
|
||||
begin
|
||||
// come back to this
|
||||
|
||||
total := total + get_mirror(map);
|
||||
|
||||
map_count := 0;
|
||||
|
||||
end
|
||||
else
|
||||
begin
|
||||
|
||||
map_count := map_count + 1;
|
||||
map.map[map_count] := s;
|
||||
map.height := map_count;
|
||||
map.width := length(s);
|
||||
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
writeln(total);
|
||||
|
||||
end.
|
||||
149
src/pascal/2023/day13/part2.pas
Normal file
149
src/pascal/2023/day13/part2.pas
Normal file
@@ -0,0 +1,149 @@
|
||||
{$mode objfpc}
|
||||
{$RANGECHECKS ON}
|
||||
|
||||
program day13part1;
|
||||
uses sysutils;
|
||||
|
||||
type
|
||||
Tmap = record
|
||||
map: array[1..100] of string;
|
||||
height: int32;
|
||||
width: int32;
|
||||
end;
|
||||
|
||||
function max(a, b: int32): int32;
|
||||
begin
|
||||
max := a;
|
||||
if b > a then
|
||||
max := b;
|
||||
end;
|
||||
|
||||
{ check for mirrors that lay vertically (column mirror) }
|
||||
function check_v_mirror(map: Tmap; col: int32): boolean;
|
||||
var
|
||||
i, j: int32;
|
||||
errors: int32;
|
||||
begin
|
||||
|
||||
errors := 0;
|
||||
for j := 1 to map.height do
|
||||
begin
|
||||
for i := max(1, 2 * col - map.width + 1) to col do
|
||||
begin
|
||||
// writeln(i, ' ', col*2 - i);
|
||||
if map.map[j, i] <> map.map[j, col * 2 - i + 1] then
|
||||
begin
|
||||
errors := errors + 1;
|
||||
if errors > 1 then
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
|
||||
if errors > 1 then
|
||||
break;
|
||||
end;
|
||||
|
||||
check_v_mirror := errors = 1;
|
||||
|
||||
end;
|
||||
|
||||
{ check for mirrors that lay vertically (column mirror) }
|
||||
function check_h_mirror(map: Tmap; row: int32): boolean;
|
||||
var
|
||||
i, j: int32;
|
||||
errors: int32;
|
||||
begin
|
||||
|
||||
errors := 0;
|
||||
for j := 1 to map.width do
|
||||
begin
|
||||
for i := max(1, 2 * row - map.height + 1) to row do
|
||||
begin
|
||||
//writeln(i, ' ', row*2 - i + 1);
|
||||
if map.map[i, j] <> map.map[row * 2 - i + 1, j] then
|
||||
begin
|
||||
errors := errors + 1;
|
||||
if errors > 1 then
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
|
||||
if errors > 1 then
|
||||
break;
|
||||
end;
|
||||
|
||||
check_h_mirror := errors = 1;
|
||||
end;
|
||||
|
||||
|
||||
function get_mirror(map: Tmap): int32;
|
||||
var
|
||||
i: int32;
|
||||
begin
|
||||
{ check vertical ones first }
|
||||
for i := 1 to map.width - 1 do
|
||||
begin
|
||||
if check_v_mirror(map, i) then
|
||||
begin
|
||||
get_mirror := i;
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ check horizontal ones now }
|
||||
for i := 1 to map.height - 1 do
|
||||
begin
|
||||
if check_h_mirror(map, i) then
|
||||
begin
|
||||
get_mirror := i shl 6 + i shl 5 + i shl 2;
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
if get_mirror = 0 then
|
||||
writeln('oh fuck');
|
||||
|
||||
end;
|
||||
|
||||
var
|
||||
|
||||
map: Tmap;
|
||||
file_: text;
|
||||
s: string;
|
||||
total, map_count: int32;
|
||||
|
||||
begin
|
||||
|
||||
assign(file_, 'resources/2023/day13.txt');
|
||||
reset(file_);
|
||||
|
||||
total := 0;
|
||||
map_count := 0;
|
||||
|
||||
while not EOF(file_) do
|
||||
begin
|
||||
|
||||
readln(file_, s);
|
||||
if length(s) = 0 then
|
||||
begin
|
||||
|
||||
total := total + get_mirror(map);
|
||||
|
||||
map_count := 0;
|
||||
|
||||
end
|
||||
else
|
||||
begin
|
||||
|
||||
map_count := map_count + 1;
|
||||
map.map[map_count] := s;
|
||||
map.height := map_count;
|
||||
map.width := length(s);
|
||||
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
writeln(total);
|
||||
|
||||
end.
|
||||
61
src/pascal/2023/day14/part1.pas
Normal file
61
src/pascal/2023/day14/part1.pas
Normal file
@@ -0,0 +1,61 @@
|
||||
{$mode objfpc}
|
||||
{$RANGECHECKS ON}
|
||||
|
||||
program day14part1;
|
||||
uses sysutils;
|
||||
|
||||
var
|
||||
|
||||
file_: text;
|
||||
s: string;
|
||||
|
||||
map: array[1..1000] of string;
|
||||
|
||||
current_boulders: int32;
|
||||
height, width: int32;
|
||||
i, j, k: int32;
|
||||
|
||||
sum: int32;
|
||||
|
||||
begin
|
||||
|
||||
assign(file_, 'resources/2023/day14.txt');
|
||||
reset(file_);
|
||||
|
||||
height := 1;
|
||||
fillchar(map[1], 255, '#');
|
||||
|
||||
while not eof(file_) do
|
||||
begin
|
||||
height := height + 1;
|
||||
readln(file_, map[height]);
|
||||
end;
|
||||
|
||||
width := length(map[2]);
|
||||
|
||||
sum := 0;
|
||||
|
||||
for i := 1 to width do
|
||||
begin
|
||||
|
||||
current_boulders := 0;
|
||||
|
||||
for j := 1 to height do
|
||||
begin
|
||||
case map[height - j + 1][i] of
|
||||
'O': current_boulders := current_boulders + 1;
|
||||
'#':
|
||||
begin
|
||||
for k := j - current_boulders to j - 1 do
|
||||
begin
|
||||
sum := sum + k;
|
||||
end;
|
||||
current_boulders := 0;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
writeln('sum: ', sum);
|
||||
|
||||
end.
|
||||
290
src/pascal/2023/day14/part2.pas
Normal file
290
src/pascal/2023/day14/part2.pas
Normal file
@@ -0,0 +1,290 @@
|
||||
{$mode objfpc}
|
||||
{$RANGECHECKS ON}
|
||||
|
||||
program day14part1;
|
||||
uses sysutils;
|
||||
|
||||
procedure print_map(map: array of string; height: int32);
|
||||
var
|
||||
i: int32;
|
||||
begin
|
||||
for i := 0 to height - 1 do
|
||||
writeln(map[i]);
|
||||
end;
|
||||
|
||||
procedure copy_map(map: array of string; var map2: array of string; height: int32);
|
||||
var
|
||||
i: int32;
|
||||
begin
|
||||
for i := 0 to height - 1 do
|
||||
map2[i] := map[i]
|
||||
end;
|
||||
|
||||
procedure shift_up(var map: array of string; height: int32; width: int32);
|
||||
var
|
||||
i, j, k: int32;
|
||||
current_boulders: int32;
|
||||
begin
|
||||
for i := 1 to width do
|
||||
begin
|
||||
|
||||
current_boulders := 0;
|
||||
|
||||
for j := 1 to height do
|
||||
begin
|
||||
case map[height - j][i] of
|
||||
'O':
|
||||
begin
|
||||
current_boulders := current_boulders + 1;
|
||||
map[height - j][i] := '.'
|
||||
end;
|
||||
'#':
|
||||
begin
|
||||
for k := height - j + 1 to height - j + current_boulders do
|
||||
begin
|
||||
map[k][i] := 'O'
|
||||
end;
|
||||
current_boulders := 0;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
for k := 0 to current_boulders - 1 do
|
||||
begin
|
||||
map[k][i] := 'O'
|
||||
end;
|
||||
current_boulders := 0;
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure shift_left(var map: array of string; height: int32; width: int32);
|
||||
var
|
||||
i, j, k: int32;
|
||||
current_boulders: int32;
|
||||
begin
|
||||
for i := 0 to height - 1 do
|
||||
begin
|
||||
|
||||
current_boulders := 0;
|
||||
|
||||
for j := 0 to width - 1 do
|
||||
begin
|
||||
case map[i][width - j] of
|
||||
'O':
|
||||
begin
|
||||
current_boulders := current_boulders + 1;
|
||||
map[i][width - j] := '.'
|
||||
end;
|
||||
'#':
|
||||
begin
|
||||
for k := width - j + 1 to width - j + current_boulders do
|
||||
begin
|
||||
map[i][k] := 'O'
|
||||
end;
|
||||
current_boulders := 0;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
for k := 1 to current_boulders do
|
||||
begin
|
||||
map[i][k] := 'O'
|
||||
end;
|
||||
current_boulders := 0;
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure shift_down(var map: array of string; height: int32; width: int32);
|
||||
var
|
||||
i, j, k: int32;
|
||||
current_boulders: int32;
|
||||
begin
|
||||
for i := 1 to width do
|
||||
begin
|
||||
|
||||
current_boulders := 0;
|
||||
|
||||
for j := 0 to height - 1 do
|
||||
begin
|
||||
case map[j][i] of
|
||||
'O':
|
||||
begin
|
||||
current_boulders := current_boulders + 1;
|
||||
map[j][i] := '.'
|
||||
end;
|
||||
'#':
|
||||
begin
|
||||
for k := j - current_boulders to j - 1 do
|
||||
begin
|
||||
map[k][i] := 'O'
|
||||
end;
|
||||
current_boulders := 0;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
for k := height - current_boulders to height - 1 do
|
||||
begin
|
||||
map[k][i] := 'O'
|
||||
end;
|
||||
current_boulders := 0;
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure shift_right(var map: array of string; height: int32; width: int32);
|
||||
var
|
||||
i, j, k: int32;
|
||||
current_boulders: int32;
|
||||
begin
|
||||
for i := 0 to height - 1 do
|
||||
begin
|
||||
|
||||
current_boulders := 0;
|
||||
|
||||
for j := 1 to width do
|
||||
begin
|
||||
case map[i][j] of
|
||||
'O':
|
||||
begin
|
||||
current_boulders := current_boulders + 1;
|
||||
map[i][j] := '.'
|
||||
end;
|
||||
'#':
|
||||
begin
|
||||
for k := j - current_boulders to j - 1 do
|
||||
begin
|
||||
map[i][k] := 'O'
|
||||
end;
|
||||
current_boulders := 0;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
for k := width - current_boulders + 1 to width do
|
||||
begin
|
||||
map[i][k] := 'O'
|
||||
end;
|
||||
current_boulders := 0;
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure spin_cycle(var map: array of string; height: int32; width: int32);
|
||||
begin
|
||||
shift_up(map, height, width);
|
||||
shift_left(map, height, width);
|
||||
shift_down(map, height, width);
|
||||
shift_right(map, height, width);
|
||||
end;
|
||||
|
||||
function calculate_load(map: array of string; height: int32): int32;
|
||||
var
|
||||
i: int32;
|
||||
c: char;
|
||||
begin
|
||||
calculate_load := 0;
|
||||
for i := 0 to height - 1 do
|
||||
begin
|
||||
for c in map[i] do
|
||||
begin
|
||||
if c = 'O' then
|
||||
calculate_load := calculate_load + height - i;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function strcomp(s1: string; s2: string): boolean;
|
||||
var
|
||||
i: int32;
|
||||
begin
|
||||
strcomp := true;
|
||||
for i := 1 to length(s1) do
|
||||
begin
|
||||
if (s1[i] <> s2[i]) then
|
||||
begin
|
||||
strcomp := false;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function map_equal(map: array of string; map2: array of string; height: int32): boolean;
|
||||
var
|
||||
i: int32;
|
||||
begin
|
||||
map_equal := true;
|
||||
for i := 0 to height - 1 do
|
||||
begin
|
||||
if not strcomp(map[i], map2[i]) then
|
||||
begin
|
||||
map_equal := false;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
var
|
||||
|
||||
file_: text;
|
||||
|
||||
map: array[1..10000, 1..100] of string;
|
||||
values: array[1..10000] of int32;
|
||||
|
||||
height, width: int32;
|
||||
i, j: int32;
|
||||
|
||||
finished: boolean;
|
||||
|
||||
wanted: int32;
|
||||
|
||||
begin
|
||||
|
||||
assign(file_, 'resources/2023/day14.txt');
|
||||
reset(file_);
|
||||
|
||||
height := 0;
|
||||
|
||||
while not eof(file_) do
|
||||
begin
|
||||
height := height + 1;
|
||||
readln(file_, map[1, height]);
|
||||
end;
|
||||
|
||||
width := length(map[1, 1]);
|
||||
values[1] := calculate_load(map[1], height);
|
||||
finished := false;
|
||||
|
||||
for i := 2 to 100000 do
|
||||
begin
|
||||
|
||||
copy_map(map[i - 1], map[i], height);
|
||||
spin_cycle(map[i], height, width);
|
||||
values[i] := calculate_load(map[i], height);
|
||||
|
||||
writeln('Found value ', values[i], ' for the ', i, 'th spin cycle');
|
||||
|
||||
for j := 1 to i - 1 do
|
||||
begin
|
||||
if map_equal(map[i], map[j], height) then
|
||||
begin
|
||||
writeln('This map is equal to the ', j, 'th map');
|
||||
finished := true;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
|
||||
if finished then
|
||||
break;
|
||||
|
||||
end;
|
||||
|
||||
wanted := 1000000000;
|
||||
|
||||
writeln('This map has a cycle length of ', i - j, 'x + ', j);
|
||||
writeln('This places ', wanted, ' at position ', (wanted - j) mod (i - j) + j + 1, ' in the cycle');
|
||||
writeln('It would have a total load of ', values[(wanted - j) mod (i - j) + j + 1]);
|
||||
|
||||
end.
|
||||
85
src/pascal/2023/day15/part1.pas
Normal file
85
src/pascal/2023/day15/part1.pas
Normal file
@@ -0,0 +1,85 @@
|
||||
{$mode objfpc}
|
||||
|
||||
program day12part1;
|
||||
uses sysutils;
|
||||
|
||||
type
|
||||
stringarray = array of string;
|
||||
|
||||
function split_to_str(s: AnsiString; delim: char): stringarray;
|
||||
var
|
||||
i, last_delim, count : int32;
|
||||
c: char;
|
||||
begin
|
||||
|
||||
{ there will always be at least one number }
|
||||
count := 1;
|
||||
{ count number of delimeters }
|
||||
for c in s do
|
||||
begin
|
||||
if c = delim then
|
||||
count := count + 1;
|
||||
end;
|
||||
|
||||
{ allocate enough space for count}
|
||||
setlength(split_to_str, count);
|
||||
|
||||
count := 0;
|
||||
last_delim := 0;
|
||||
|
||||
{ second interation }
|
||||
for i := 1 to length(s) do
|
||||
begin
|
||||
{ if this is a delimeter }
|
||||
if s[i] = delim then
|
||||
begin
|
||||
{ add the value between this delimiter and the previous one to splitted }
|
||||
split_to_str[count] := copy(s, last_delim + 1, i - last_delim - 1);
|
||||
count := count + 1;
|
||||
last_delim := i;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ don't forget the final value }
|
||||
split_to_str[count] := copy(s, last_delim + 1, length(s) - last_delim)
|
||||
end;
|
||||
|
||||
function hash(s: string): int32;
|
||||
var
|
||||
c: char;
|
||||
begin
|
||||
hash := 0;
|
||||
for c in s do
|
||||
hash := ((hash + ord(c)) * 17) and 255;
|
||||
|
||||
|
||||
end;
|
||||
|
||||
var
|
||||
|
||||
s: AnsiString;
|
||||
to_hash: array of string;
|
||||
|
||||
split: array of string;
|
||||
|
||||
file_: text;
|
||||
|
||||
sum: int32;
|
||||
|
||||
begin
|
||||
|
||||
assign(file_, 'resources/2023/day15.txt');
|
||||
reset(file_);
|
||||
readln(file_, s);
|
||||
|
||||
to_hash := split_to_str(s, ',');
|
||||
writeln(length(to_hash));
|
||||
|
||||
sum := 0;
|
||||
|
||||
for s in to_hash do
|
||||
sum := sum + hash(s);
|
||||
|
||||
writeln('The sum is ', sum);
|
||||
end.
|
||||
|
||||
194
src/pascal/2023/day15/part2.pas
Normal file
194
src/pascal/2023/day15/part2.pas
Normal file
@@ -0,0 +1,194 @@
|
||||
{$mode objfpc}
|
||||
|
||||
program day12part1;
|
||||
uses sysutils;
|
||||
|
||||
type
|
||||
stringarray = array of string;
|
||||
lens = record
|
||||
label_: string;
|
||||
focal: int32;
|
||||
end;
|
||||
|
||||
|
||||
function split_to_str(s: AnsiString; delim: char): stringarray;
|
||||
var
|
||||
i, last_delim, count : int32;
|
||||
c: char;
|
||||
begin
|
||||
|
||||
{ there will always be at least one number }
|
||||
count := 1;
|
||||
{ count number of delimeters }
|
||||
for c in s do
|
||||
begin
|
||||
if c = delim then
|
||||
count := count + 1;
|
||||
end;
|
||||
|
||||
{ allocate enough space for count}
|
||||
setlength(split_to_str, count);
|
||||
|
||||
count := 0;
|
||||
last_delim := 0;
|
||||
|
||||
{ second interation }
|
||||
for i := 1 to length(s) do
|
||||
begin
|
||||
{ if this is a delimeter }
|
||||
if s[i] = delim then
|
||||
begin
|
||||
{ add the value between this delimiter and the previous one to splitted }
|
||||
split_to_str[count] := copy(s, last_delim + 1, i - last_delim - 1);
|
||||
count := count + 1;
|
||||
last_delim := i;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ don't forget the final value }
|
||||
split_to_str[count] := copy(s, last_delim + 1, length(s) - last_delim)
|
||||
end;
|
||||
|
||||
function streq(s1: string; s2: string): boolean;
|
||||
var
|
||||
i: int32;
|
||||
begin
|
||||
streq := true;
|
||||
for i := 1 to length(s1) do
|
||||
begin
|
||||
if (s1[i] <> s2[i]) then
|
||||
begin
|
||||
streq := false;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function hash(s: string): int32;
|
||||
var
|
||||
c: char;
|
||||
begin
|
||||
hash := 0;
|
||||
for c in s do
|
||||
hash := ((hash + ord(c)) * 17) and 255;
|
||||
|
||||
|
||||
end;
|
||||
|
||||
var
|
||||
{ ideally a linked list would be nice for the second dim, but eh.}
|
||||
boxes: array[0..255, 1..100] of lens;
|
||||
b_length: array[0..255] of int32;
|
||||
|
||||
procedure insert_lens(l: string; f: int32);
|
||||
var
|
||||
hvalue: int32;
|
||||
i: int32;
|
||||
begin
|
||||
|
||||
hvalue := hash(l);
|
||||
|
||||
{ check for duplicate }
|
||||
for i := 1 to b_length[hvalue] do
|
||||
begin
|
||||
if streq(boxes[hvalue, i].label_, l) then
|
||||
begin
|
||||
boxes[hvalue, i].focal := f;
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ add to end }
|
||||
|
||||
b_length[hvalue] := b_length[hvalue] + 1;
|
||||
boxes[hvalue, b_length[hvalue]].label_ := l;
|
||||
boxes[hvalue, b_length[hvalue]].focal := f;
|
||||
|
||||
end;
|
||||
|
||||
procedure remove_lens(l: string);
|
||||
var
|
||||
hvalue: int32;
|
||||
i: int32;
|
||||
shifting: boolean;
|
||||
begin
|
||||
hvalue := hash(l);
|
||||
|
||||
shifting := false;
|
||||
for i := 1 to b_length[hvalue] do
|
||||
begin
|
||||
if shifting then
|
||||
boxes[hvalue, i - 1] := boxes[hvalue, i]
|
||||
else if streq(boxes[hvalue, i].label_, l) then
|
||||
shifting := true;
|
||||
end;
|
||||
|
||||
if shifting then
|
||||
b_length[hvalue] := b_length[hvalue] - 1;
|
||||
end;
|
||||
|
||||
procedure write_boxes();
|
||||
var
|
||||
i, j: int32;
|
||||
begin
|
||||
|
||||
for i := 0 to 255 do
|
||||
begin
|
||||
if b_length[i] <> 0 then
|
||||
begin
|
||||
|
||||
write('Box ', i, ': ');
|
||||
|
||||
for j := 1 to b_length[i] do
|
||||
begin
|
||||
write('[', boxes[i, j].label_, ' ', boxes[i, j].focal, '] ');
|
||||
end;
|
||||
|
||||
writeln();
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
var
|
||||
|
||||
s: AnsiString;
|
||||
to_hash: array of string;
|
||||
|
||||
split: array of string;
|
||||
|
||||
file_: text;
|
||||
|
||||
i, j: int32;
|
||||
sum: int32;
|
||||
|
||||
begin
|
||||
|
||||
assign(file_, 'resources/2023/day15.txt');
|
||||
reset(file_);
|
||||
readln(file_, s);
|
||||
|
||||
to_hash := split_to_str(s, ',');
|
||||
|
||||
{ fill boxes }
|
||||
for s in to_hash do
|
||||
begin
|
||||
if s[length(s)] = '-' then
|
||||
remove_lens(copy(s, 0, length(s) - 1))
|
||||
else if s[length(s) - 1] = '=' then
|
||||
begin
|
||||
val(s[length(s)], i);
|
||||
insert_lens(copy(s, 0, length(s) - 2), i);
|
||||
end;
|
||||
end;
|
||||
|
||||
{ sum }
|
||||
sum := 0;
|
||||
for i := 0 to 255 do
|
||||
for j := 1 to b_length[i] do
|
||||
sum := sum + (i + 1) * j * boxes[i, j].focal;
|
||||
|
||||
|
||||
write_boxes();
|
||||
writeln('The sum is ', sum);
|
||||
end.
|
||||
|
||||
146
src/pascal/2023/day16/part1.pas
Normal file
146
src/pascal/2023/day16/part1.pas
Normal file
@@ -0,0 +1,146 @@
|
||||
{$mode objfpc}
|
||||
{$RANGECHECKS ON}
|
||||
|
||||
program day16part1;
|
||||
uses sysutils;
|
||||
|
||||
type
|
||||
Tdirection = (Left, Up, Right, Down, NA);
|
||||
|
||||
var
|
||||
map: array[1..1000] of string;
|
||||
illuminated: array[1..1000, 1..1000] of boolean;
|
||||
splitted: array[1..1000, 1..1000] of boolean;
|
||||
height, width: int32;
|
||||
|
||||
procedure print_illuminated();
|
||||
var
|
||||
i, j: int32;
|
||||
begin
|
||||
for i := 1 to height do
|
||||
begin
|
||||
for j := 1 to width do
|
||||
case illuminated[i, j] of
|
||||
true: write('#');
|
||||
false: write('.');
|
||||
end;
|
||||
writeln();
|
||||
end;
|
||||
end;
|
||||
|
||||
function sum_illuminated(): int32;
|
||||
var
|
||||
i, j: int32;
|
||||
begin
|
||||
|
||||
sum_illuminated := 0;
|
||||
|
||||
for i := 1 to height do
|
||||
for j := 1 to width do
|
||||
if illuminated[i, j] then
|
||||
sum_illuminated := sum_illuminated + 1;
|
||||
end;
|
||||
|
||||
procedure step_illumination(x, y: int32; dir: Tdirection);
|
||||
begin
|
||||
|
||||
{ range check }
|
||||
if (x < 1) or (x > width) or (y < 1) or (y > height) then
|
||||
exit;
|
||||
|
||||
writeln('(', x, ',', y, ')');
|
||||
|
||||
illuminated[y, x] := true;
|
||||
|
||||
{ nested case my beloved }
|
||||
case map[y, x] of
|
||||
'.':
|
||||
begin
|
||||
{ continue same direction }
|
||||
case dir of
|
||||
Up: step_illumination(x, y - 1, Up);
|
||||
Left: step_illumination(x - 1, y, Left);
|
||||
Down: step_illumination(x, y + 1, Down);
|
||||
Right: step_illumination(x + 1, y, Right);
|
||||
end;
|
||||
end;
|
||||
'/':
|
||||
begin
|
||||
{ reflect direction }
|
||||
case dir of
|
||||
Up: step_illumination(x + 1, y, Right);
|
||||
Left: step_illumination(x, y + 1, Down);
|
||||
Down: step_illumination(x - 1, y, Left);
|
||||
Right: step_illumination(x, y - 1, Up);
|
||||
end;
|
||||
end;
|
||||
'\':
|
||||
begin
|
||||
{ reflect direction but in the other way}
|
||||
case dir of
|
||||
Up: step_illumination(x - 1, y, Left);
|
||||
Left: step_illumination(x, y - 1, Up);
|
||||
Down: step_illumination(x + 1, y, Right);
|
||||
Right: step_illumination(x, y + 1, Down);
|
||||
end;
|
||||
end;
|
||||
'|':
|
||||
begin
|
||||
{ up down passthrough, left right split }
|
||||
case dir of
|
||||
Up: step_illumination(x, y - 1, Up);
|
||||
Down: step_illumination(x, y + 1, Down);
|
||||
Left, Right:
|
||||
begin
|
||||
if not splitted[y, x] then // so we don't split forever in a loop
|
||||
begin
|
||||
splitted[y, x] := true;
|
||||
step_illumination(x, y - 1, Up);
|
||||
step_illumination(x, y + 1, Down);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
'-':
|
||||
begin
|
||||
{ lr passthrough, ud split }
|
||||
case dir of
|
||||
Left: step_illumination(x - 1, y, Left);
|
||||
Right: step_illumination(x + 1, y, Right);
|
||||
Up, Down:
|
||||
begin
|
||||
if not splitted[y, x] then // so we don't split forever in a loop
|
||||
begin
|
||||
splitted[y, x] := true;
|
||||
step_illumination(x - 1, y, Left);
|
||||
step_illumination(x + 1, y, Right);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
var
|
||||
|
||||
file_: text;
|
||||
|
||||
begin
|
||||
|
||||
assign(file_, 'resources/2023/day16.txt');
|
||||
reset(file_);
|
||||
|
||||
height := 0;
|
||||
|
||||
while not eof(file_) do
|
||||
begin
|
||||
height := height + 1;
|
||||
readln(file_, map[height]);
|
||||
end;
|
||||
width := length(map[1]);
|
||||
|
||||
step_illumination(1, 1, Right);
|
||||
print_illuminated();
|
||||
writeln('Total illuminated is ', sum_illuminated());
|
||||
|
||||
end.
|
||||
219
src/pascal/2023/day16/part2.pas
Normal file
219
src/pascal/2023/day16/part2.pas
Normal file
@@ -0,0 +1,219 @@
|
||||
{$mode objfpc}
|
||||
{$RANGECHECKS ON}
|
||||
|
||||
program day16part1;
|
||||
uses sysutils;
|
||||
|
||||
type
|
||||
Tdirection = (Left, Up, Right, Down, NA);
|
||||
|
||||
var
|
||||
map: array[1..1000] of string;
|
||||
illuminated: array[1..1000, 1..1000] of boolean;
|
||||
splitted: array[1..1000, 1..1000] of boolean;
|
||||
height, width: int32;
|
||||
|
||||
procedure print_illuminated();
|
||||
var
|
||||
i, j: int32;
|
||||
begin
|
||||
for i := 1 to height do
|
||||
begin
|
||||
for j := 1 to width do
|
||||
case illuminated[i, j] of
|
||||
true: write('#');
|
||||
false: write('.');
|
||||
end;
|
||||
writeln();
|
||||
end;
|
||||
end;
|
||||
|
||||
function sum_illuminated(): int32;
|
||||
var
|
||||
i, j: int32;
|
||||
begin
|
||||
|
||||
sum_illuminated := 0;
|
||||
|
||||
for i := 1 to height do
|
||||
for j := 1 to width do
|
||||
if illuminated[i, j] then
|
||||
sum_illuminated := sum_illuminated + 1;
|
||||
end;
|
||||
|
||||
procedure reset_illuminated_splitted();
|
||||
var
|
||||
i, j: int32;
|
||||
begin
|
||||
for i := 1 to height do
|
||||
for j := 1 to width do
|
||||
begin
|
||||
illuminated[j, i] := false;
|
||||
splitted[j, i] := false;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure step_illumination(x, y: int32; dir: Tdirection);
|
||||
begin
|
||||
|
||||
{ range check }
|
||||
if (x < 1) or (x > width) or (y < 1) or (y > height) then
|
||||
exit;
|
||||
|
||||
illuminated[y, x] := true;
|
||||
|
||||
{ nested case my beloved }
|
||||
case map[y, x] of
|
||||
'.':
|
||||
begin
|
||||
{ continue same direction }
|
||||
case dir of
|
||||
Up: step_illumination(x, y - 1, Up);
|
||||
Left: step_illumination(x - 1, y, Left);
|
||||
Down: step_illumination(x, y + 1, Down);
|
||||
Right: step_illumination(x + 1, y, Right);
|
||||
end;
|
||||
end;
|
||||
'/':
|
||||
begin
|
||||
{ reflect direction }
|
||||
case dir of
|
||||
Up: step_illumination(x + 1, y, Right);
|
||||
Left: step_illumination(x, y + 1, Down);
|
||||
Down: step_illumination(x - 1, y, Left);
|
||||
Right: step_illumination(x, y - 1, Up);
|
||||
end;
|
||||
end;
|
||||
'\':
|
||||
begin
|
||||
{ reflect direction but in the other way}
|
||||
case dir of
|
||||
Up: step_illumination(x - 1, y, Left);
|
||||
Left: step_illumination(x, y - 1, Up);
|
||||
Down: step_illumination(x + 1, y, Right);
|
||||
Right: step_illumination(x, y + 1, Down);
|
||||
end;
|
||||
end;
|
||||
'|':
|
||||
begin
|
||||
{ up down passthrough, left right split }
|
||||
case dir of
|
||||
Up: step_illumination(x, y - 1, Up);
|
||||
Down: step_illumination(x, y + 1, Down);
|
||||
Left, Right:
|
||||
begin
|
||||
if not splitted[y, x] then // so we don't split forever in a loop
|
||||
begin
|
||||
splitted[y, x] := true;
|
||||
step_illumination(x, y - 1, Up);
|
||||
step_illumination(x, y + 1, Down);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
'-':
|
||||
begin
|
||||
{ lr passthrough, ud split }
|
||||
case dir of
|
||||
Left: step_illumination(x - 1, y, Left);
|
||||
Right: step_illumination(x + 1, y, Right);
|
||||
Up, Down:
|
||||
begin
|
||||
if not splitted[y, x] then // so we don't split forever in a loop
|
||||
begin
|
||||
splitted[y, x] := true;
|
||||
step_illumination(x - 1, y, Left);
|
||||
step_illumination(x + 1, y, Right);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
var
|
||||
|
||||
file_: text;
|
||||
|
||||
max: int32;
|
||||
i, t: int32;
|
||||
|
||||
// for pretty printing
|
||||
max_dir: Tdirection;
|
||||
max_idx: int32;
|
||||
|
||||
begin
|
||||
|
||||
assign(file_, 'resources/2023/day16.txt');
|
||||
reset(file_);
|
||||
|
||||
height := 0;
|
||||
|
||||
while not eof(file_) do
|
||||
begin
|
||||
height := height + 1;
|
||||
readln(file_, map[height]);
|
||||
end;
|
||||
width := length(map[1]);
|
||||
|
||||
max := -1;
|
||||
max_dir := NA;
|
||||
max_idx := -1;
|
||||
|
||||
{ check up + down }
|
||||
for i := 1 to width do
|
||||
begin
|
||||
step_illumination(i, 1, Down);
|
||||
t := sum_illuminated();
|
||||
reset_illuminated_splitted();
|
||||
|
||||
if t > max then
|
||||
begin
|
||||
max := t;
|
||||
max_dir := Down;
|
||||
max_idx := i;
|
||||
end;
|
||||
|
||||
step_illumination(i, height, Up);
|
||||
t := sum_illuminated();
|
||||
reset_illuminated_splitted();
|
||||
|
||||
if t > max then
|
||||
begin
|
||||
max := t;
|
||||
max_dir := Up;
|
||||
max_idx := i;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ check left + right }
|
||||
for i := 1 to height do
|
||||
begin
|
||||
step_illumination(1, i, Right);
|
||||
t := sum_illuminated();
|
||||
reset_illuminated_splitted();
|
||||
|
||||
if t > max then
|
||||
begin
|
||||
max := t;
|
||||
max_dir := Right;
|
||||
max_idx := i;
|
||||
end;
|
||||
|
||||
step_illumination(width, i, Left);
|
||||
t := sum_illuminated();
|
||||
reset_illuminated_splitted();
|
||||
|
||||
if t > max then
|
||||
begin
|
||||
max := t;
|
||||
max_dir := Left;
|
||||
max_idx := i;
|
||||
end;
|
||||
end;
|
||||
|
||||
writeln('The best configuration is going ', max_dir, ' at index ', max_idx);
|
||||
writeln('The max illumination is ', max);
|
||||
|
||||
|
||||
end.
|
||||
14
src/pascal/2023/day17/part1.pas
Normal file
14
src/pascal/2023/day17/part1.pas
Normal file
@@ -0,0 +1,14 @@
|
||||
{$mode objfpc}
|
||||
{$RANGECHECKS ON}
|
||||
|
||||
program day17part1;
|
||||
uses sysutils;
|
||||
|
||||
type
|
||||
Tnode = record
|
||||
x, y: int32;
|
||||
end;
|
||||
|
||||
begin
|
||||
|
||||
end.
|
||||
23
src/pascal/2023/day17/queue.pas
Normal file
23
src/pascal/2023/day17/queue.pas
Normal file
@@ -0,0 +1,23 @@
|
||||
// i wrote this but i didn't use it
|
||||
// might be useful for the future;
|
||||
|
||||
var
|
||||
queue: array[0..1000] of Tnode;
|
||||
queue_start, queue_length: int32;
|
||||
|
||||
procedure enqueue(node: Tnode);
|
||||
begin
|
||||
queue[queue_start + queue_length] := node;
|
||||
inc(queue_length);
|
||||
end;
|
||||
|
||||
function dequeue(): Tnode;
|
||||
begin
|
||||
dequeue := queue[queue_start];
|
||||
inc(queue_start);
|
||||
dec(queue_length);
|
||||
end;
|
||||
|
||||
var
|
||||
|
||||
a, b: Tnode;
|
||||
141
src/pascal/2023/day2/part1.pas
Normal file
141
src/pascal/2023/day2/part1.pas
Normal file
@@ -0,0 +1,141 @@
|
||||
program day2part2;
|
||||
|
||||
var
|
||||
file_: text;
|
||||
str: string;
|
||||
sum, game: int32;
|
||||
state: int32;
|
||||
number: int32;
|
||||
|
||||
i: int32;
|
||||
c: char;
|
||||
|
||||
red_limit: int32 = 12;
|
||||
green_limit: int32 = 13;
|
||||
blue_limit: int32 = 14;
|
||||
|
||||
(* Here the main program block starts *)
|
||||
begin
|
||||
{ open inp.txt for reading }
|
||||
assign(file_, 'resources/2023/day2.txt');
|
||||
reset(file_);
|
||||
|
||||
{ initialize sum and count to 0 }
|
||||
game := 0;
|
||||
sum := 0;
|
||||
|
||||
{ until the file is empty }
|
||||
while not eof(file_) do
|
||||
begin
|
||||
|
||||
{ increment game counter }
|
||||
game := game + 1;
|
||||
|
||||
{ assume this game is fine and valid }
|
||||
sum := sum + game;
|
||||
|
||||
{ read a line from the file }
|
||||
readln(file_, str);
|
||||
|
||||
{ state of current searching }
|
||||
state := 0;
|
||||
{ 0 = initial, going to colon -> 1}
|
||||
{ 1 = wasting a space, resetting number -> 2}
|
||||
{ 2 = searching for number -> 3}
|
||||
{ 3 = checking color -> 4 }
|
||||
{ 4 = waiting for space -> 2}
|
||||
|
||||
|
||||
for c in str do
|
||||
begin
|
||||
|
||||
{ holy case statement. }
|
||||
|
||||
case state of
|
||||
{seeking to first colon}
|
||||
0:
|
||||
begin
|
||||
{colon, move to state 1}
|
||||
if (c = ':') then
|
||||
state := 1
|
||||
end;
|
||||
{wasting a space}
|
||||
1:
|
||||
begin
|
||||
{move to state 2, initialize number}
|
||||
state := 2;
|
||||
number := 0;
|
||||
end;
|
||||
{reading number}
|
||||
2:
|
||||
begin
|
||||
{if number}
|
||||
if (('0' <= c) and (c <= '9')) then
|
||||
begin
|
||||
{add number to number}
|
||||
val(c, i);
|
||||
number := number * 10 + i;
|
||||
end;
|
||||
{at the end move to state 3}
|
||||
if (c = ' ') then
|
||||
state := 3
|
||||
end;
|
||||
{check color}
|
||||
3:
|
||||
begin
|
||||
{check red}
|
||||
if (c = 'r') then
|
||||
begin
|
||||
{if there's too many}
|
||||
if (number > red_limit) then
|
||||
begin
|
||||
{set this game as invalid and break}
|
||||
sum := sum - game;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
|
||||
{check blue}
|
||||
if (c = 'b') then
|
||||
begin
|
||||
{if there's too many}
|
||||
if (number > blue_limit) then
|
||||
begin
|
||||
{set this game as invalid and break}
|
||||
sum := sum - game;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
|
||||
{check green}
|
||||
if (c = 'g') then
|
||||
begin
|
||||
{if there's too many}
|
||||
if (number > green_limit) then
|
||||
begin
|
||||
{set this game as invalid and break}
|
||||
sum := sum - game;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
|
||||
{if we're still here, move to state 4}
|
||||
state := 4;
|
||||
end;
|
||||
{wait for a space}
|
||||
4:
|
||||
begin
|
||||
if (c = ' ') then
|
||||
begin
|
||||
{reset number and go back to state 2}
|
||||
number := 0;
|
||||
state := 2;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ print out that beautiful sum }
|
||||
writeln(sum);
|
||||
end.
|
||||
130
src/pascal/2023/day2/part2.pas
Normal file
130
src/pascal/2023/day2/part2.pas
Normal file
@@ -0,0 +1,130 @@
|
||||
program day2part2;
|
||||
|
||||
var
|
||||
file_: text;
|
||||
str: string;
|
||||
sum: int32;
|
||||
state: int32;
|
||||
number: int32;
|
||||
|
||||
i: int32;
|
||||
c: char;
|
||||
|
||||
rcount, gcount, bcount: int32;
|
||||
|
||||
(* Here the main program block starts *)
|
||||
begin
|
||||
{ open inp.txt for reading }
|
||||
assign(file_, 'resources/2023/day2.txt');
|
||||
reset(file_);
|
||||
|
||||
{ initialize sum to 0 }
|
||||
sum := 0;
|
||||
|
||||
{ until the file is empty }
|
||||
while not eof(file_) do
|
||||
begin
|
||||
|
||||
|
||||
{ read a line from the file }
|
||||
readln(file_, str);
|
||||
|
||||
{ state of current searching }
|
||||
state := 0;
|
||||
{ 0 = initial, going to colon -> 1}
|
||||
{ 1 = wasting a space, resetting number -> 2}
|
||||
{ 2 = searching for number -> 3}
|
||||
{ 3 = checking color -> 4 }
|
||||
{ 4 = waiting for space -> 2}
|
||||
|
||||
{ initialize counts to zero }
|
||||
rcount := 0;
|
||||
bcount := 0;
|
||||
gcount := 0;
|
||||
|
||||
|
||||
for c in str do
|
||||
begin
|
||||
|
||||
{ holy case statement. }
|
||||
|
||||
case state of
|
||||
{seeking to first colon}
|
||||
0:
|
||||
begin
|
||||
{colon, move to state 1}
|
||||
if (c = ':') then
|
||||
state := 1
|
||||
end;
|
||||
{wasting a space}
|
||||
1:
|
||||
begin
|
||||
{move to state 2, initialize number}
|
||||
state := 2;
|
||||
number := 0;
|
||||
end;
|
||||
{reading number}
|
||||
2:
|
||||
begin
|
||||
{if number}
|
||||
if (('0' <= c) and (c <= '9')) then
|
||||
begin
|
||||
{add number to number}
|
||||
val(c, i);
|
||||
number := number * 10 + i;
|
||||
end;
|
||||
{at the end move to state 3}
|
||||
if (c = ' ') then
|
||||
state := 3
|
||||
end;
|
||||
{update color}
|
||||
3:
|
||||
begin
|
||||
{check red}
|
||||
if (c = 'r') then
|
||||
begin
|
||||
{update red if it's max}
|
||||
if (number > rcount) then
|
||||
rcount := number
|
||||
end;
|
||||
|
||||
{check blue}
|
||||
if (c = 'b') then
|
||||
begin
|
||||
{update blue if it's max}
|
||||
if (number > bcount) then
|
||||
bcount := number
|
||||
end;
|
||||
|
||||
{check green}
|
||||
if (c = 'g') then
|
||||
begin
|
||||
{update green if it's max}
|
||||
if (number > gcount) then
|
||||
gcount := number
|
||||
end;
|
||||
|
||||
{if we're still here, move to state 4}
|
||||
state := 4;
|
||||
end;
|
||||
{wait for a space}
|
||||
4:
|
||||
begin
|
||||
if (c = ' ') then
|
||||
begin
|
||||
{reset number and go back to state 2}
|
||||
number := 0;
|
||||
state := 2;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ increase sum }
|
||||
sum := sum + rcount * bcount * gcount;
|
||||
|
||||
end;
|
||||
|
||||
{ print out that beautiful sum }
|
||||
writeln(sum);
|
||||
end.
|
||||
238
src/pascal/2023/day3/part1.pas
Normal file
238
src/pascal/2023/day3/part1.pas
Normal file
@@ -0,0 +1,238 @@
|
||||
program day3part1;
|
||||
uses sysutils;
|
||||
|
||||
var
|
||||
file_: text;
|
||||
prev, curr, next: string;
|
||||
sum, game: int32;
|
||||
state: int32;
|
||||
number: int32;
|
||||
valid: boolean;
|
||||
|
||||
i, b: int32;
|
||||
c: char;
|
||||
|
||||
LINE_LENGTH: int32 = 140;
|
||||
|
||||
function is_symbol(str: string; ind: int32): boolean;
|
||||
begin
|
||||
is_symbol := ((not ((ind < 1) or (ind > LINE_LENGTH))) and (('0' > str[ind]) or (str[ind] > '9')) and (str[ind] <> '.'));
|
||||
end;
|
||||
|
||||
function is_ok(prev: string; curr: string; next: string; ind: int32): boolean;
|
||||
begin
|
||||
is_ok := is_symbol(curr, i-1);
|
||||
is_ok := (is_ok or is_symbol(curr, i+1));
|
||||
is_ok := (is_ok or is_symbol(next, i-1));
|
||||
is_ok := (is_ok or is_symbol(next, i));
|
||||
is_ok := (is_ok or is_symbol(next, i+1));
|
||||
is_ok := (is_ok or is_symbol(prev, i-1));
|
||||
is_ok := (is_ok or is_symbol(prev, i));
|
||||
is_ok := (is_ok or is_symbol(prev, i+1));
|
||||
end;
|
||||
|
||||
|
||||
(* Here the main program block starts *)
|
||||
begin
|
||||
{ open inp.txt for reading }
|
||||
assign(file_, 'resources/2023/day3.txt');
|
||||
reset(file_);
|
||||
|
||||
{ initialize sum and count to 0 }
|
||||
sum := 0;
|
||||
|
||||
{ read the first two lines }
|
||||
readln(file_, curr);
|
||||
readln(file_, next);
|
||||
|
||||
writeln(length(curr));
|
||||
|
||||
writeln(booltostr(true));
|
||||
writeln(booltostr(false));
|
||||
|
||||
{ writeln(curr); }
|
||||
{ writeln(next); }
|
||||
|
||||
state := 0;
|
||||
number := 0;
|
||||
{ 0 : waiting for number }
|
||||
{ 1 : reading number }
|
||||
|
||||
{ first loop }
|
||||
for i := 1 to LINE_LENGTH do
|
||||
begin
|
||||
c := curr[i];
|
||||
case state of
|
||||
{waiting for number}
|
||||
0:
|
||||
begin
|
||||
{number}
|
||||
if (('0' <= c) and (c <= '9')) then
|
||||
begin
|
||||
{add number to number}
|
||||
val(c, number);
|
||||
valid := false;
|
||||
state := 1;
|
||||
|
||||
valid := (valid or is_ok(next, curr, next, i-1));
|
||||
|
||||
end;
|
||||
end;
|
||||
{reading number and checking true}
|
||||
1:
|
||||
begin
|
||||
if (('0' <= c) and (c <= '9')) then
|
||||
begin
|
||||
{add number to number}
|
||||
val(c, b);
|
||||
number := number * 10 + b;
|
||||
|
||||
{look for symbol}
|
||||
|
||||
valid := (valid or is_ok(next, curr, next, i-1));
|
||||
|
||||
end
|
||||
else
|
||||
begin
|
||||
state := 0;
|
||||
|
||||
if (valid) then
|
||||
sum := sum + number;
|
||||
|
||||
end;
|
||||
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ main loop }
|
||||
while not eof(file_) do
|
||||
begin
|
||||
|
||||
state := 0;
|
||||
|
||||
prev := curr;
|
||||
curr := next;
|
||||
readln(file_, next);
|
||||
|
||||
writeln();
|
||||
writeln(prev);
|
||||
writeln(curr);
|
||||
writeln(next);
|
||||
|
||||
for i := 1 to LINE_LENGTH do
|
||||
begin
|
||||
c := curr[i];
|
||||
case state of
|
||||
{waiting for number}
|
||||
0:
|
||||
begin
|
||||
{number}
|
||||
if (('0' <= c) and (c <= '9')) then
|
||||
begin
|
||||
{add number to number}
|
||||
val(c, number);
|
||||
valid := false;
|
||||
state := 1;
|
||||
|
||||
valid := (valid or is_ok(prev, curr, next, i-1));
|
||||
|
||||
end;
|
||||
end;
|
||||
{reading number and checking true}
|
||||
1:
|
||||
begin
|
||||
if (('0' <= c) and (c <= '9')) then
|
||||
begin
|
||||
{add number to number}
|
||||
val(c, b);
|
||||
number := number * 10 + b;
|
||||
|
||||
{look for symbol}
|
||||
|
||||
valid := (valid or is_ok(prev, curr, next, i-1));
|
||||
|
||||
end
|
||||
else
|
||||
begin
|
||||
state := 0;
|
||||
|
||||
if (valid) then
|
||||
sum := sum + number;
|
||||
|
||||
end;
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
write(state);
|
||||
|
||||
end;
|
||||
|
||||
if (state = 1) then
|
||||
begin
|
||||
begin
|
||||
|
||||
if (valid) then
|
||||
sum := sum + number;
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
state := 0;
|
||||
|
||||
prev := curr;
|
||||
curr := next;
|
||||
|
||||
|
||||
for i := 1 to LINE_LENGTH do
|
||||
begin
|
||||
c := curr[i];
|
||||
case state of
|
||||
{waiting for number}
|
||||
0:
|
||||
begin
|
||||
{number}
|
||||
if (('0' <= c) and (c <= '9')) then
|
||||
begin
|
||||
{add number to number}
|
||||
val(c, number);
|
||||
valid := false;
|
||||
state := 1;
|
||||
|
||||
valid := (valid or is_ok(prev, curr, prev, i-1));
|
||||
|
||||
end;
|
||||
end;
|
||||
{reading number and checking true}
|
||||
1:
|
||||
begin
|
||||
if (('0' <= c) and (c <= '9')) then
|
||||
begin
|
||||
{add number to number}
|
||||
val(c, b);
|
||||
number := number * 10 + b;
|
||||
|
||||
{look for symbol}
|
||||
|
||||
valid := (valid or is_ok(prev, curr, prev, i-1));
|
||||
|
||||
end
|
||||
else
|
||||
begin
|
||||
state := 0;
|
||||
|
||||
if (valid) then
|
||||
sum := sum + number;
|
||||
|
||||
end;
|
||||
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
writeln();
|
||||
writeln(sum);
|
||||
end.
|
||||
224
src/pascal/2023/day3/part2.pas
Normal file
224
src/pascal/2023/day3/part2.pas
Normal file
@@ -0,0 +1,224 @@
|
||||
program day3part2;
|
||||
uses sysutils;
|
||||
|
||||
var
|
||||
file_: text;
|
||||
curr: string;
|
||||
sum, game: int32;
|
||||
state: int32;
|
||||
number: int32;
|
||||
valid: boolean;
|
||||
|
||||
i, a, b: int32;
|
||||
line: int32;
|
||||
c: char;
|
||||
|
||||
LINE_LENGTH: int32 = 140;
|
||||
|
||||
curr_asterisk: int32;
|
||||
asterisks: int32;
|
||||
asterisk_values: array[1..1000] of int32;
|
||||
asterisk_locations: array[1..1000, 1..2] of int32;
|
||||
|
||||
function is_symbol(str: string; ind: int32): boolean;
|
||||
begin
|
||||
is_symbol := (str[ind] = '*')
|
||||
end;
|
||||
|
||||
function find_asterisk(hpos: int32; vpos: int32): int32;
|
||||
var
|
||||
j: int32;
|
||||
|
||||
begin
|
||||
|
||||
find_asterisk := -1;
|
||||
|
||||
for j := 1 to asterisks do
|
||||
begin
|
||||
if ((asterisk_locations[j, 1] = hpos) and (asterisk_locations[j, 2] = vpos)) then
|
||||
begin
|
||||
find_asterisk := j;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function get_asterisk_id(hpos: int32; vpos: int32): int32;
|
||||
var
|
||||
fucked_up: int32;
|
||||
|
||||
begin
|
||||
|
||||
get_asterisk_id := -1;
|
||||
|
||||
fucked_up := find_asterisk(hpos-1, vpos-1);
|
||||
if (fucked_up <> -1) then
|
||||
get_asterisk_id := fucked_up;
|
||||
fucked_up := find_asterisk(hpos, vpos-1);
|
||||
if (fucked_up <> -1) then
|
||||
get_asterisk_id := fucked_up;
|
||||
fucked_up := find_asterisk(hpos+1, vpos-1);
|
||||
if (fucked_up <> -1) then
|
||||
get_asterisk_id := fucked_up;
|
||||
fucked_up := find_asterisk(hpos-1, vpos);
|
||||
if (fucked_up <> -1) then
|
||||
get_asterisk_id := fucked_up;
|
||||
fucked_up := find_asterisk(hpos+1, vpos);
|
||||
if (fucked_up <> -1) then
|
||||
get_asterisk_id := fucked_up;
|
||||
fucked_up := find_asterisk(hpos-1, vpos+1);
|
||||
if (fucked_up <> -1) then
|
||||
get_asterisk_id := fucked_up;
|
||||
fucked_up := find_asterisk(hpos, vpos+1);
|
||||
if (fucked_up <> -1) then
|
||||
get_asterisk_id := fucked_up;
|
||||
fucked_up := find_asterisk(hpos+1, vpos+1);
|
||||
if (fucked_up <> -1) then
|
||||
get_asterisk_id := fucked_up;
|
||||
|
||||
end;
|
||||
|
||||
(* Here the main program block starts *)
|
||||
begin
|
||||
{ open inp.txt for reading }
|
||||
assign(file_, 'resources/2023/day3.txt');
|
||||
reset(file_);
|
||||
|
||||
{ initialize sum and count to 0 }
|
||||
sum := 0;
|
||||
|
||||
{ read the first two lines }
|
||||
|
||||
line := 1;
|
||||
asterisks := 0;
|
||||
|
||||
|
||||
{find the position of all asterisks}
|
||||
|
||||
while not eof(file_) do
|
||||
begin
|
||||
|
||||
readln(file_, curr);
|
||||
|
||||
for i := 1 to LINE_LENGTH do
|
||||
begin
|
||||
if is_symbol(curr, i) then
|
||||
begin
|
||||
asterisk_locations[asterisks + 1][1] := i;
|
||||
asterisk_locations[asterisks + 1][2] := line;
|
||||
|
||||
asterisk_values[asterisks + 1] := 0;
|
||||
|
||||
asterisks := asterisks + 1;
|
||||
end;
|
||||
end;
|
||||
|
||||
line := line + 1;
|
||||
|
||||
end;
|
||||
|
||||
line := 0;
|
||||
|
||||
reset(file_);
|
||||
|
||||
writeln('boobs');
|
||||
|
||||
{ main loop }
|
||||
while not eof(file_) do
|
||||
begin
|
||||
|
||||
state := 0;
|
||||
line := line + 1;
|
||||
|
||||
readln(file_, curr);
|
||||
|
||||
for i := 1 to LINE_LENGTH do
|
||||
begin
|
||||
c := curr[i];
|
||||
write(c);
|
||||
case state of
|
||||
{waiting for number}
|
||||
0:
|
||||
begin
|
||||
{number}
|
||||
if (('0' <= c) and (c <= '9')) then
|
||||
begin
|
||||
{add number to number}
|
||||
val(c, number);
|
||||
state := 1;
|
||||
|
||||
curr_asterisk := get_asterisk_id(i, line);
|
||||
|
||||
end;
|
||||
end;
|
||||
{reading number and checking true}
|
||||
1:
|
||||
begin
|
||||
if (('0' <= c) and (c <= '9')) then
|
||||
begin
|
||||
|
||||
writeln('boobs2');
|
||||
|
||||
{add number to number}
|
||||
val(c, b);
|
||||
number := number * 10 + b;
|
||||
|
||||
{look for symbol}
|
||||
b := get_asterisk_id(i, line);
|
||||
if (b <> -1) then
|
||||
curr_asterisk := b;
|
||||
|
||||
end
|
||||
else
|
||||
begin
|
||||
state := 0;
|
||||
writeln(curr_asterisk);
|
||||
|
||||
if (curr_asterisk <> -1) then
|
||||
begin
|
||||
if (asterisk_values[curr_asterisk] = 0) then
|
||||
asterisk_values[curr_asterisk] := number
|
||||
else if (asterisk_values[curr_asterisk] > 0) then
|
||||
begin
|
||||
sum := sum + asterisk_values[curr_asterisk] * number;
|
||||
asterisk_values[curr_asterisk] := -1;
|
||||
end;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
write(state);
|
||||
|
||||
end;
|
||||
|
||||
if (state = 1) then
|
||||
begin
|
||||
begin
|
||||
|
||||
if (curr_asterisk <> -1) then
|
||||
begin
|
||||
if (asterisk_values[curr_asterisk] = 0) then
|
||||
asterisk_values[curr_asterisk] := number
|
||||
else if (asterisk_values[curr_asterisk] > 0) then
|
||||
begin
|
||||
sum := sum + asterisk_values[curr_asterisk] * number;
|
||||
asterisk_values[curr_asterisk] := -1;
|
||||
end;
|
||||
end;
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
i := get_asterisk_id(114, 126);
|
||||
writeln(i);
|
||||
writeln(asterisk_locations[i, 1]);
|
||||
writeln(asterisk_locations[i, 2]);
|
||||
writeln(sum);
|
||||
|
||||
|
||||
end.
|
||||
141
src/pascal/2023/day4/part1.pas
Normal file
141
src/pascal/2023/day4/part1.pas
Normal file
@@ -0,0 +1,141 @@
|
||||
program day4part1;
|
||||
uses sysutils;
|
||||
|
||||
type
|
||||
MState = (ToColon, WasteSpace, ReadWin, WasteSpace2, ReadHave);
|
||||
|
||||
var
|
||||
state: MState;
|
||||
file_: text;
|
||||
str: string;
|
||||
number: int32;
|
||||
|
||||
winning: array[1..100] of int32;
|
||||
have: array[1..100] of int32;
|
||||
|
||||
winning_length, have_length: int32;
|
||||
|
||||
b, d: int32;
|
||||
c: char;
|
||||
i, j: int32;
|
||||
|
||||
scores: array[0..10] of int32 = (0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512);
|
||||
|
||||
sum: int32;
|
||||
|
||||
begin
|
||||
{ open inp.txt for reading }
|
||||
assign(file_, 'resources/2023/day4.txt');
|
||||
reset(file_);
|
||||
|
||||
sum := 0;
|
||||
|
||||
while not EOF(file_) do
|
||||
begin
|
||||
|
||||
{ state of current searching }
|
||||
state := ToColon;
|
||||
|
||||
{ read in a file}
|
||||
readln(file_, str);
|
||||
|
||||
fillchar(have[1], sizeof(have), 0);
|
||||
fillchar(winning[1], sizeof(winning), 0);
|
||||
|
||||
for c in str do
|
||||
begin
|
||||
|
||||
{ holy case statement. }
|
||||
case state of
|
||||
ToColon:
|
||||
begin
|
||||
if (c = ':') then
|
||||
state := WasteSpace
|
||||
end;
|
||||
|
||||
WasteSpace:
|
||||
begin
|
||||
state := ReadWin;
|
||||
number := 0;
|
||||
winning_length := 1;
|
||||
end;
|
||||
ReadWin:
|
||||
begin
|
||||
if (('0' <= c) and (c <= '9')) then
|
||||
begin
|
||||
{add number to number}
|
||||
val(c, b);
|
||||
number := number * 10 + b;
|
||||
end
|
||||
else if (c = ' ') then
|
||||
begin
|
||||
winning[winning_length] := number;
|
||||
winning_length := winning_length + 1;
|
||||
number := 0;
|
||||
end
|
||||
else if (c = '|') then
|
||||
begin
|
||||
state := WasteSpace2;
|
||||
number := 0;
|
||||
end;
|
||||
end;
|
||||
WasteSpace2:
|
||||
begin
|
||||
state := ReadHave;
|
||||
number := 0;
|
||||
have_length := 1;
|
||||
end;
|
||||
ReadHave:
|
||||
begin
|
||||
if (('0' <= c) and (c <= '9')) then
|
||||
begin
|
||||
{add number to number}
|
||||
val(c, b);
|
||||
number := number * 10 + b;
|
||||
end
|
||||
else if (c = ' ') then
|
||||
begin
|
||||
have[have_length] := number;
|
||||
have_length := have_length + 1;
|
||||
number := 0;
|
||||
end
|
||||
else if (c = '|') then
|
||||
begin
|
||||
state := WasteSpace2;
|
||||
number := 0;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
have[have_length] := number;
|
||||
have_length := have_length + 1;
|
||||
|
||||
d := 0;
|
||||
for i in winning do
|
||||
begin
|
||||
if (i = 0) then
|
||||
begin
|
||||
continue;
|
||||
end;
|
||||
|
||||
|
||||
for j in have do
|
||||
begin
|
||||
if (j = 0) then
|
||||
begin
|
||||
continue;
|
||||
end;
|
||||
|
||||
if (i = j) then
|
||||
d := d + 1
|
||||
end;
|
||||
end;
|
||||
|
||||
sum := sum + scores[d];
|
||||
|
||||
end;
|
||||
|
||||
writeln(sum);
|
||||
|
||||
end.
|
||||
154
src/pascal/2023/day4/part2.pas
Normal file
154
src/pascal/2023/day4/part2.pas
Normal file
@@ -0,0 +1,154 @@
|
||||
program day4part2;
|
||||
uses sysutils;
|
||||
|
||||
type
|
||||
MState = (ToColon, WasteSpace, ReadWin, WasteSpace2, ReadHave);
|
||||
|
||||
var
|
||||
state: MState;
|
||||
file_: text;
|
||||
str: string;
|
||||
number: int32;
|
||||
cardnum: int32;
|
||||
|
||||
winning: array[1..100] of int32;
|
||||
have: array[1..100] of int32;
|
||||
|
||||
copies: array[1..1000] of int32;
|
||||
|
||||
winning_length, have_length: int32;
|
||||
|
||||
b, d: int32;
|
||||
c: char;
|
||||
i, j: int32;
|
||||
|
||||
sum: int32;
|
||||
|
||||
begin
|
||||
{ open inp.txt for reading }
|
||||
assign(file_, 'resources/2023/day4.txt');
|
||||
reset(file_);
|
||||
|
||||
filldword(copies, length(copies), 1);
|
||||
|
||||
sum := 0;
|
||||
cardnum := 0;
|
||||
|
||||
while not EOF(file_) do
|
||||
begin
|
||||
|
||||
cardnum := cardnum + 1;
|
||||
|
||||
{ state of current searching }
|
||||
state := ToColon;
|
||||
|
||||
{ read in a file}
|
||||
readln(file_, str);
|
||||
|
||||
fillchar(have[1], sizeof(have), 0);
|
||||
fillchar(winning[1], sizeof(winning), 0);
|
||||
|
||||
for c in str do
|
||||
begin
|
||||
|
||||
{ holy case statement. }
|
||||
case state of
|
||||
ToColon:
|
||||
begin
|
||||
if (c = ':') then
|
||||
state := WasteSpace
|
||||
end;
|
||||
|
||||
WasteSpace:
|
||||
begin
|
||||
state := ReadWin;
|
||||
number := 0;
|
||||
winning_length := 1;
|
||||
end;
|
||||
ReadWin:
|
||||
begin
|
||||
if (('0' <= c) and (c <= '9')) then
|
||||
begin
|
||||
{add number to number}
|
||||
val(c, b);
|
||||
number := number * 10 + b;
|
||||
end
|
||||
else if (c = ' ') then
|
||||
begin
|
||||
winning[winning_length] := number;
|
||||
winning_length := winning_length + 1;
|
||||
number := 0;
|
||||
end
|
||||
else if (c = '|') then
|
||||
begin
|
||||
state := WasteSpace2;
|
||||
number := 0;
|
||||
end;
|
||||
end;
|
||||
WasteSpace2:
|
||||
begin
|
||||
state := ReadHave;
|
||||
number := 0;
|
||||
have_length := 1;
|
||||
end;
|
||||
ReadHave:
|
||||
begin
|
||||
if (('0' <= c) and (c <= '9')) then
|
||||
begin
|
||||
{add number to number}
|
||||
val(c, b);
|
||||
number := number * 10 + b;
|
||||
end
|
||||
else if (c = ' ') then
|
||||
begin
|
||||
have[have_length] := number;
|
||||
have_length := have_length + 1;
|
||||
number := 0;
|
||||
end
|
||||
else if (c = '|') then
|
||||
begin
|
||||
state := WasteSpace2;
|
||||
number := 0;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
have[have_length] := number;
|
||||
have_length := have_length + 1;
|
||||
|
||||
d := 0;
|
||||
for i in winning do
|
||||
begin
|
||||
if (i = 0) then
|
||||
begin
|
||||
continue;
|
||||
end;
|
||||
|
||||
for j in have do
|
||||
begin
|
||||
if (j = 0) then
|
||||
begin
|
||||
continue;
|
||||
end;
|
||||
|
||||
if (i = j) then
|
||||
d := d + 1
|
||||
end;
|
||||
end;
|
||||
|
||||
for i := 1 to d do
|
||||
begin
|
||||
copies[cardnum + i] := copies[cardnum + i] + copies[cardnum];
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
for i := 1 to cardnum do
|
||||
begin
|
||||
sum := sum + copies[i];
|
||||
end;
|
||||
|
||||
writeln(sum);
|
||||
|
||||
end.
|
||||
163
src/pascal/2023/day5/part1.pas
Normal file
163
src/pascal/2023/day5/part1.pas
Normal file
@@ -0,0 +1,163 @@
|
||||
program day5part1;
|
||||
uses sysutils;
|
||||
|
||||
type
|
||||
SState = (ToColon, WasteSpace, ReadSeeds, NewLine);
|
||||
MState = (Seed, WaitMap, ReadMap);
|
||||
|
||||
|
||||
var
|
||||
|
||||
seeds: array[1..20] of int64;
|
||||
next_seeds: array[1..20] of int64;
|
||||
map: array[1..3] of int64;
|
||||
|
||||
seed_length: int64;
|
||||
cmap: int64;
|
||||
|
||||
seed_state: SState;
|
||||
state: MState;
|
||||
file_: text;
|
||||
str: string;
|
||||
number: int64;
|
||||
|
||||
c: char;
|
||||
i, j, b: int64;
|
||||
|
||||
srange, erange: int64;
|
||||
|
||||
begin
|
||||
{ open inp.txt for reading }
|
||||
assign(file_, 'resources/2023/day5.txt');
|
||||
reset(file_);
|
||||
|
||||
state := Seed;
|
||||
|
||||
while not EOF(file_) do
|
||||
begin
|
||||
|
||||
{ read in a file}
|
||||
readln(file_, str);
|
||||
|
||||
case state of
|
||||
Seed:
|
||||
begin
|
||||
seed_state := ToColon;
|
||||
for c in str do
|
||||
begin
|
||||
case seed_state of
|
||||
ToColon:
|
||||
begin
|
||||
if (c = ':') then
|
||||
seed_state := WasteSpace
|
||||
end;
|
||||
WasteSpace:
|
||||
begin
|
||||
seed_state := ReadSeeds;
|
||||
number := 0;
|
||||
seed_length := 0;
|
||||
end;
|
||||
ReadSeeds:
|
||||
begin
|
||||
if (('0' <= c) and (c <= '9')) then
|
||||
begin
|
||||
{add number to number}
|
||||
val(c, b);
|
||||
number := number * 10 + b;
|
||||
end
|
||||
else if (c = ' ') then
|
||||
begin
|
||||
seed_length := seed_length + 1;
|
||||
seeds[seed_length] := number;
|
||||
number := 0;
|
||||
end
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
seed_length := seed_length + 1;
|
||||
seeds[seed_length] := number;
|
||||
|
||||
fillqword(next_seeds, length(next_seeds), 18446744073709551615);
|
||||
state := WaitMap;
|
||||
end;
|
||||
WaitMap:
|
||||
if (length(str) > 0) then
|
||||
begin
|
||||
state := ReadMap;
|
||||
|
||||
{ change this later because this is wrong }
|
||||
|
||||
for i := 0 to length(seeds) do
|
||||
begin
|
||||
if (next_seeds[i] <> -1) then
|
||||
seeds[i] := next_seeds[i]
|
||||
end;
|
||||
|
||||
{ this is -1 }
|
||||
fillqword(next_seeds, length(next_seeds), 18446744073709551615);
|
||||
|
||||
writeln('break');
|
||||
end;
|
||||
ReadMap:
|
||||
begin
|
||||
|
||||
if (length(str) = 0) then
|
||||
begin
|
||||
state := WaitMap;
|
||||
continue;
|
||||
end;
|
||||
|
||||
cmap := 0;
|
||||
number := 0;
|
||||
|
||||
for c in str do
|
||||
begin
|
||||
if (('0' <= c) and (c <= '9')) then
|
||||
begin
|
||||
{add number to number}
|
||||
val(c, b);
|
||||
number := number * 10 + b;
|
||||
end
|
||||
else if (c = ' ') then
|
||||
begin
|
||||
cmap := cmap + 1;
|
||||
map[cmap] := number;
|
||||
number := 0;
|
||||
end;
|
||||
end;
|
||||
|
||||
cmap := cmap + 1;
|
||||
map[cmap] := number;
|
||||
|
||||
srange := map[2];
|
||||
erange := map[2] + map[3] - 1;
|
||||
|
||||
for i := 1 to length(seeds) do
|
||||
begin
|
||||
if ((seeds[i] >= srange) and (seeds[i] <= erange)) then
|
||||
begin
|
||||
next_seeds[i] := seeds[i] - srange + map[1];
|
||||
end;
|
||||
end;
|
||||
|
||||
writeln();
|
||||
for i in next_seeds do
|
||||
writeln(i);
|
||||
end;
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
writeln();
|
||||
|
||||
for i := 0 to length(seeds) do
|
||||
begin
|
||||
if (next_seeds[i] <> -1) then
|
||||
seeds[i] := next_seeds[i]
|
||||
end;
|
||||
|
||||
for i in seeds do
|
||||
writeln(i);
|
||||
|
||||
end.
|
||||
272
src/pascal/2023/day5/part2.pas
Normal file
272
src/pascal/2023/day5/part2.pas
Normal file
@@ -0,0 +1,272 @@
|
||||
program day5part1;
|
||||
uses sysutils;
|
||||
|
||||
type
|
||||
SState = (ToColon, WasteSpace, ReadSeeds, NewLine);
|
||||
MState = (Seed, WaitMap, ReadMap, Q);
|
||||
|
||||
|
||||
var
|
||||
|
||||
seeds: array[1..100000] of int64;
|
||||
next_seeds: array[1..100000] of int64;
|
||||
map: array[1..3] of int64;
|
||||
|
||||
seed_length: int64;
|
||||
cmap: int64;
|
||||
|
||||
seed_state: SState;
|
||||
state: MState;
|
||||
file_: text;
|
||||
str: string;
|
||||
number: int64;
|
||||
|
||||
c: char;
|
||||
i, b: int64;
|
||||
|
||||
srange, erange: int64;
|
||||
sseed, eseed: int64;
|
||||
|
||||
times: int64;
|
||||
|
||||
procedure add_seed(a: int64; b: int64);
|
||||
begin
|
||||
seeds[seed_length + 1] := a;
|
||||
seeds[seed_length + 2] := b - a + 1;
|
||||
seed_length := seed_length + 2;
|
||||
end;
|
||||
|
||||
begin
|
||||
{ open inp.txt for reading }
|
||||
assign(file_, 'resources/2023/day5.txt');
|
||||
reset(file_);
|
||||
|
||||
times := 0;
|
||||
state := Seed;
|
||||
|
||||
while not EOF(file_) do
|
||||
begin
|
||||
|
||||
{ read in a file}
|
||||
readln(file_, str);
|
||||
|
||||
case state of
|
||||
Seed:
|
||||
begin
|
||||
seed_state := ToColon;
|
||||
for c in str do
|
||||
begin
|
||||
case seed_state of
|
||||
ToColon:
|
||||
begin
|
||||
if (c = ':') then
|
||||
seed_state := WasteSpace
|
||||
end;
|
||||
WasteSpace:
|
||||
begin
|
||||
seed_state := ReadSeeds;
|
||||
number := 0;
|
||||
seed_length := 0;
|
||||
end;
|
||||
ReadSeeds:
|
||||
begin
|
||||
if (('0' <= c) and (c <= '9')) then
|
||||
begin
|
||||
{add number to number}
|
||||
val(c, b);
|
||||
number := number * 10 + b;
|
||||
end
|
||||
else if (c = ' ') then
|
||||
begin
|
||||
seed_length := seed_length + 1;
|
||||
seeds[seed_length] := number;
|
||||
number := 0;
|
||||
end
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
seed_length := seed_length + 1;
|
||||
seeds[seed_length] := number;
|
||||
|
||||
fillqword(next_seeds, length(next_seeds), 18446744073709551615);
|
||||
state := WaitMap;
|
||||
end;
|
||||
WaitMap:
|
||||
if (length(str) > 0) then
|
||||
begin
|
||||
state := ReadMap;
|
||||
|
||||
{ change this later because this is wrong }
|
||||
|
||||
for i := 0 to length(seeds) do
|
||||
begin
|
||||
if (next_seeds[i] <> -1) then
|
||||
seeds[i] := next_seeds[i]
|
||||
end;
|
||||
|
||||
{ this is -1 }
|
||||
fillqword(next_seeds, length(next_seeds), 18446744073709551615);
|
||||
|
||||
writeln('break');
|
||||
for i := 1 to seed_length do
|
||||
begin
|
||||
write(seeds[i]);
|
||||
write(' ');
|
||||
end;
|
||||
|
||||
writeln();
|
||||
end;
|
||||
ReadMap:
|
||||
begin
|
||||
|
||||
if (length(str) = 0) then
|
||||
begin
|
||||
state := WaitMap;
|
||||
continue;
|
||||
end;
|
||||
|
||||
cmap := 0;
|
||||
number := 0;
|
||||
|
||||
for c in str do
|
||||
begin
|
||||
if (('0' <= c) and (c <= '9')) then
|
||||
begin
|
||||
{add number to number}
|
||||
val(c, b);
|
||||
number := number * 10 + b;
|
||||
end
|
||||
else if (c = ' ') then
|
||||
begin
|
||||
cmap := cmap + 1;
|
||||
map[cmap] := number;
|
||||
number := 0;
|
||||
end;
|
||||
end;
|
||||
|
||||
cmap := cmap + 1;
|
||||
map[cmap] := number;
|
||||
|
||||
srange := map[2];
|
||||
erange := map[2] + map[3] - 1;
|
||||
|
||||
write('here we go: ');
|
||||
writeln(times);
|
||||
|
||||
for i := 1 to length(seeds) do
|
||||
begin
|
||||
if ((i and 1) = 0) then
|
||||
continue;
|
||||
if (seeds[i + 1] = 0) then
|
||||
continue;
|
||||
if (i >= seed_length) then
|
||||
break;
|
||||
writeln(i);
|
||||
|
||||
sseed := seeds[i];
|
||||
eseed := seeds[i] + seeds[i + 1] - 1;
|
||||
|
||||
write(sseed);
|
||||
write(' ');
|
||||
writeln(eseed);
|
||||
|
||||
srange := map[2];
|
||||
erange := map[2] + map[3] - 1;
|
||||
|
||||
write(srange);
|
||||
write(' ');
|
||||
writeln(erange);
|
||||
|
||||
{ range contained }
|
||||
if ((eseed > erange) and (sseed < srange)) then
|
||||
begin
|
||||
writeln('range contained');
|
||||
{ add the right tail }
|
||||
add_seed(erange + 1, eseed);
|
||||
{ add the left tail }
|
||||
add_seed(sseed, srange - 1);
|
||||
|
||||
next_seeds[i + 1] := erange - srange;
|
||||
next_seeds[i] := map[1];
|
||||
seeds[i + 1] := 0;
|
||||
|
||||
end
|
||||
{ left tailed }
|
||||
else if ((eseed > erange) and (erange >= sseed)) then
|
||||
begin
|
||||
writeln('left');
|
||||
{ add the right tail}
|
||||
add_seed(erange + 1, eseed);
|
||||
{ update length }
|
||||
next_seeds[i + 1] := erange - sseed + 1;
|
||||
{ adjust according to map }
|
||||
next_seeds[i] := map[1] + sseed - srange;
|
||||
seeds[i + 1] := 0;
|
||||
|
||||
end
|
||||
{ right tailed }
|
||||
else if ((eseed >= srange) and (srange > sseed)) then
|
||||
begin
|
||||
writeln('right');
|
||||
{ add the left tail}
|
||||
add_seed(sseed, srange - 1);
|
||||
{ update length }
|
||||
next_seeds[i + 1] := eseed - srange + 1;
|
||||
{ adjust according to map }
|
||||
next_seeds[i] := map[1];
|
||||
seeds[i + 1] := 0;
|
||||
end
|
||||
else if ((srange <= sseed) and (eseed <= erange)) then
|
||||
begin
|
||||
writeln('easy mode');
|
||||
next_seeds[i] := map[1] + sseed - srange;
|
||||
end
|
||||
else
|
||||
begin
|
||||
writeln('GOD FUCKING DAMMIT');
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
writeln();
|
||||
for i := 1 to seed_length do
|
||||
begin
|
||||
write(next_seeds[i]);
|
||||
write(' ');
|
||||
end;
|
||||
writeln();
|
||||
for i := 1 to seed_length do
|
||||
begin
|
||||
write(seeds[i]);
|
||||
write(' ');
|
||||
end;
|
||||
writeln();
|
||||
writeln(seed_length);
|
||||
|
||||
writeln('next');
|
||||
|
||||
times := times + 1;
|
||||
{ if (times = 6) then
|
||||
break;}
|
||||
end;
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
writeln();
|
||||
|
||||
for i := 0 to length(seeds) do
|
||||
begin
|
||||
if (next_seeds[i] <> -1) then
|
||||
seeds[i] := next_seeds[i]
|
||||
end;
|
||||
|
||||
for i := 1 to seed_length do
|
||||
begin;
|
||||
if ((i and 1) = 0) then
|
||||
continue;
|
||||
writeln(seeds[i]);
|
||||
end;
|
||||
|
||||
end.
|
||||
35
src/pascal/2023/day6/part1.pas
Normal file
35
src/pascal/2023/day6/part1.pas
Normal file
@@ -0,0 +1,35 @@
|
||||
program day5part1;
|
||||
uses sysutils;
|
||||
|
||||
type
|
||||
SState = (ToColon, WasteSpace, ReadSeeds, NewLine);
|
||||
MState = (Seed, WaitMap, ReadMap);
|
||||
|
||||
|
||||
var
|
||||
|
||||
race_times: array of int32 = (57, 72, 69, 92);
|
||||
race_distances: array of int32 = (291, 1172, 1176, 2026);
|
||||
valid: array of int32 = (0, 0, 0, 0);
|
||||
|
||||
i, j: int32;
|
||||
|
||||
begin
|
||||
|
||||
for i := 0 to 3 do
|
||||
begin
|
||||
writeln(race_times[i]);
|
||||
writeln(race_distances[i]);
|
||||
|
||||
for j := 1 to race_times[i] do
|
||||
begin
|
||||
|
||||
if (race_times[i] - j) * j > race_distances[i] then
|
||||
valid[i] := valid[i] + 1
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
writeln(valid[0] * valid[1] * valid[2] * valid[3])
|
||||
|
||||
end.
|
||||
32
src/pascal/2023/day6/part2.pas
Normal file
32
src/pascal/2023/day6/part2.pas
Normal file
@@ -0,0 +1,32 @@
|
||||
program day5part1;
|
||||
uses sysutils;
|
||||
|
||||
type
|
||||
SState = (ToColon, WasteSpace, ReadSeeds, NewLine);
|
||||
MState = (Seed, WaitMap, ReadMap);
|
||||
|
||||
|
||||
var
|
||||
|
||||
race_time: int64 = 57726992;
|
||||
race_distance: int64 = 291117211762026;
|
||||
valid: int64 = 0;
|
||||
|
||||
i, j: int32;
|
||||
|
||||
begin
|
||||
|
||||
writeln(race_time);
|
||||
writeln(race_distance);
|
||||
|
||||
for j := 1 to race_time do
|
||||
begin
|
||||
|
||||
if (race_time - j) * j > race_distance then
|
||||
valid := valid + 1
|
||||
|
||||
end;
|
||||
|
||||
writeln(valid);
|
||||
|
||||
end.
|
||||
188
src/pascal/2023/day7/part1.pas
Normal file
188
src/pascal/2023/day7/part1.pas
Normal file
@@ -0,0 +1,188 @@
|
||||
program day5part1;
|
||||
uses sysutils;
|
||||
|
||||
type
|
||||
MState = (ReadCards, ReadBet);
|
||||
|
||||
|
||||
var
|
||||
|
||||
|
||||
state: MState;
|
||||
file_: text;
|
||||
|
||||
c: char;
|
||||
i, j, b: int64;
|
||||
|
||||
sum, count: int32;
|
||||
|
||||
rank: array[1..1000] of int32;
|
||||
bet: array[1..1000] of int32;
|
||||
|
||||
line: string;
|
||||
|
||||
|
||||
function CardToValue(inp: char): int32;
|
||||
begin
|
||||
case inp of
|
||||
'A': CardToValue := 12;
|
||||
'K': CardToValue := 11;
|
||||
'Q': CardToValue := 10;
|
||||
'J': CardToValue := 9;
|
||||
'T': CardToValue := 8;
|
||||
'9': CardToValue := 7;
|
||||
'8': CardToValue := 6;
|
||||
'7': CardToValue := 5;
|
||||
'6': CardToValue := 4;
|
||||
'5': CardToValue := 3;
|
||||
'4': CardToValue := 2;
|
||||
'3': CardToValue := 1;
|
||||
'2': CardToValue := 0;
|
||||
end;
|
||||
end;
|
||||
|
||||
function HandToValue(inp: string): int32;
|
||||
var
|
||||
|
||||
c: char;
|
||||
type_, hand_value: int32;
|
||||
counts: array[0..12] of int32;
|
||||
duos, trips, quads, quints: int32;
|
||||
|
||||
i: int32;
|
||||
|
||||
begin
|
||||
|
||||
filldword(counts, length(counts), 0);
|
||||
|
||||
for c in inp do
|
||||
counts[CardToValue(c)] := counts[CardToValue(c)] + 1;
|
||||
|
||||
duos := 0;
|
||||
trips := 0;
|
||||
quads := 0;
|
||||
quints := 0;
|
||||
|
||||
for i in counts do
|
||||
begin
|
||||
if (i = 2) then
|
||||
duos := duos + 1
|
||||
else if (i = 3) then
|
||||
trips := trips + 1
|
||||
else if (i = 4) then
|
||||
quads := quads + 1
|
||||
else if (i = 5) then
|
||||
quints := quints + 1
|
||||
|
||||
end;
|
||||
|
||||
{5K, 4K, FH, 3K, 2P, 1P, HC}
|
||||
{ 7, 6, 5, 4, 3, 2, 1}
|
||||
if (quints = 1) then
|
||||
type_ := 7
|
||||
else if (quads = 1) then
|
||||
type_ := 6
|
||||
else if ((trips = 1) and (duos = 1)) then
|
||||
type_ := 5
|
||||
else if (trips = 1) then
|
||||
type_ := 4
|
||||
else if (duos = 2) then
|
||||
type_ := 3
|
||||
else if (duos = 1) then
|
||||
type_ := 2
|
||||
else
|
||||
type_ := 1;
|
||||
|
||||
hand_value := CardToValue(inp[1]) * 28561 + CardToValue(inp[2]) * 2197 + CardToValue(inp[3]) * 169 + CardToValue(inp[4]) * 13 + CardToValue(inp[5]);
|
||||
|
||||
HandToValue := 371293 * type_ + hand_value;
|
||||
|
||||
end;
|
||||
|
||||
procedure DoubleSort(var arr1: array of int32; var arr2: array of int32; l: int32);
|
||||
var
|
||||
|
||||
i, t: int32;
|
||||
swapped: boolean;
|
||||
|
||||
begin
|
||||
|
||||
while (true) do
|
||||
begin
|
||||
swapped := false;
|
||||
for i := 1 to l-1 do
|
||||
begin
|
||||
if (arr1[i-1] > arr1[i]) then
|
||||
begin
|
||||
t := arr1[i-1];
|
||||
arr1[i-1] := arr1[i];
|
||||
arr1[i] := t;
|
||||
|
||||
t := arr2[i-1];
|
||||
arr2[i-1] := arr2[i];
|
||||
arr2[i] := t;
|
||||
|
||||
swapped := true;
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
if (not swapped) then
|
||||
break;
|
||||
|
||||
end
|
||||
|
||||
end;
|
||||
|
||||
|
||||
begin
|
||||
|
||||
{ open inp.txt for reading }
|
||||
assign(file_, 'resources/2023/day7.txt');
|
||||
reset(file_);
|
||||
|
||||
count := 0;
|
||||
|
||||
while not EOF(file_) do
|
||||
begin
|
||||
count := count + 1;
|
||||
|
||||
readln(file_, line);
|
||||
|
||||
writeln(count);
|
||||
|
||||
writeln(line);
|
||||
|
||||
rank[count] := HandToValue(copy(line, 1, 5));
|
||||
val(copy(line, 6, length(line) - 5), bet[count]);
|
||||
|
||||
write(rank[count]);
|
||||
write(' ');
|
||||
writeln(bet[count]);
|
||||
|
||||
end;
|
||||
|
||||
writeln('a');
|
||||
for i := 1 to count do
|
||||
writeln(rank[i]);
|
||||
writeln();
|
||||
|
||||
doublesort(rank, bet, count);
|
||||
|
||||
writeln(rank[count]);
|
||||
writeln(bet[count]);
|
||||
|
||||
sum := 0;
|
||||
|
||||
writeln('a');
|
||||
for i := 1 to count do
|
||||
writeln(rank[i]);
|
||||
writeln();
|
||||
|
||||
for i := 1 to count do
|
||||
|
||||
sum := sum + bet[i] * i;
|
||||
|
||||
writeln(sum);
|
||||
|
||||
end.
|
||||
199
src/pascal/2023/day7/part2.pas
Normal file
199
src/pascal/2023/day7/part2.pas
Normal file
@@ -0,0 +1,199 @@
|
||||
program day5part1;
|
||||
uses sysutils;
|
||||
|
||||
type
|
||||
MState = (ReadCards, ReadBet);
|
||||
|
||||
|
||||
var
|
||||
|
||||
|
||||
state: MState;
|
||||
file_: text;
|
||||
|
||||
c: char;
|
||||
i, j, b: int64;
|
||||
|
||||
sum, count: int32;
|
||||
|
||||
rank: array[1..1000] of int32;
|
||||
bet: array[1..1000] of int32;
|
||||
|
||||
line: string;
|
||||
|
||||
|
||||
function CardToValue(inp: char): int32;
|
||||
begin
|
||||
case inp of
|
||||
'A': CardToValue := 12;
|
||||
'K': CardToValue := 11;
|
||||
'Q': CardToValue := 10;
|
||||
'T': CardToValue := 9;
|
||||
'9': CardToValue := 8;
|
||||
'8': CardToValue := 7;
|
||||
'7': CardToValue := 6;
|
||||
'6': CardToValue := 5;
|
||||
'5': CardToValue := 4;
|
||||
'4': CardToValue := 3;
|
||||
'3': CardToValue := 2;
|
||||
'2': CardToValue := 1;
|
||||
'J': CardToValue := 0;
|
||||
end;
|
||||
end;
|
||||
|
||||
function HandToValue(inp: string): int32;
|
||||
var
|
||||
|
||||
c: char;
|
||||
type_, hand_value: int32;
|
||||
counts: array[0..12] of int32;
|
||||
duos, trips, quads, quints: int32;
|
||||
|
||||
jokes: int32;
|
||||
|
||||
i: int32;
|
||||
|
||||
begin
|
||||
|
||||
filldword(counts, length(counts), 0);
|
||||
|
||||
for c in inp do
|
||||
counts[CardToValue(c)] := counts[CardToValue(c)] + 1;
|
||||
|
||||
duos := 0;
|
||||
trips := 0;
|
||||
quads := 0;
|
||||
quints := 0;
|
||||
|
||||
jokes := counts[0];
|
||||
{ reset jokes so that they won't be counted}
|
||||
counts[0] := 0;
|
||||
|
||||
for i in counts do
|
||||
begin
|
||||
if (i + jokes = 2) then
|
||||
duos := duos + 1
|
||||
else if (i + jokes = 3) then
|
||||
trips := trips + 1
|
||||
else if (i + jokes = 4) then
|
||||
quads := quads + 1
|
||||
else if (i + jokes = 5) then
|
||||
quints := quints + 1
|
||||
|
||||
end;
|
||||
|
||||
{5K, 4K, FH, 3K, 2P, 1P, HC}
|
||||
{ 7, 6, 5, 4, 3, 2, 1}
|
||||
if ((quints = 1) or (jokes = 5)) then
|
||||
type_ := 7
|
||||
else if (quads >= 1) then
|
||||
type_ := 6
|
||||
else if ((trips = 1) and (duos = 1)) or (trips = 2) then
|
||||
type_ := 5
|
||||
else if (trips >= 1) then
|
||||
type_ := 4
|
||||
else if (duos = 2) then
|
||||
type_ := 3
|
||||
else if (duos >= 1) then
|
||||
type_ := 2
|
||||
else
|
||||
type_ := 1;
|
||||
|
||||
writeln(inp);
|
||||
writeln(type_);
|
||||
|
||||
hand_value := CardToValue(inp[1]) * 28561 + CardToValue(inp[2]) * 2197 + CardToValue(inp[3]) * 169 + CardToValue(inp[4]) * 13 + CardToValue(inp[5]);
|
||||
|
||||
writeln(hand_value);
|
||||
|
||||
HandToValue := 371293 * type_ + hand_value;
|
||||
|
||||
end;
|
||||
|
||||
procedure DoubleSort(var arr1: array of int32; var arr2: array of int32; l: int32);
|
||||
var
|
||||
|
||||
i, t: int32;
|
||||
swapped: boolean;
|
||||
|
||||
begin
|
||||
|
||||
while (true) do
|
||||
begin
|
||||
swapped := false;
|
||||
for i := 1 to l-1 do
|
||||
begin
|
||||
if (arr1[i-1] > arr1[i]) then
|
||||
begin
|
||||
t := arr1[i-1];
|
||||
arr1[i-1] := arr1[i];
|
||||
arr1[i] := t;
|
||||
|
||||
t := arr2[i-1];
|
||||
arr2[i-1] := arr2[i];
|
||||
arr2[i] := t;
|
||||
|
||||
swapped := true;
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
if (not swapped) then
|
||||
break;
|
||||
|
||||
end
|
||||
|
||||
end;
|
||||
|
||||
|
||||
begin
|
||||
|
||||
{ open inp.txt for reading }
|
||||
assign(file_, 'resources/2023/day7.txt');
|
||||
reset(file_);
|
||||
|
||||
count := 0;
|
||||
|
||||
while not EOF(file_) do
|
||||
begin
|
||||
count := count + 1;
|
||||
|
||||
readln(file_, line);
|
||||
|
||||
writeln(count);
|
||||
|
||||
writeln(line);
|
||||
|
||||
rank[count] := HandToValue(copy(line, 1, 5));
|
||||
val(copy(line, 6, length(line) - 5), bet[count]);
|
||||
|
||||
write(rank[count]);
|
||||
write(' ');
|
||||
writeln(bet[count]);
|
||||
|
||||
end;
|
||||
|
||||
writeln('a');
|
||||
for i := 1 to count do
|
||||
writeln(rank[i]);
|
||||
writeln();
|
||||
|
||||
doublesort(rank, bet, count);
|
||||
|
||||
writeln(rank[count]);
|
||||
writeln(bet[count]);
|
||||
|
||||
sum := 0;
|
||||
|
||||
writeln('a');
|
||||
for i := 1 to count do
|
||||
writeln(rank[i]);
|
||||
writeln();
|
||||
|
||||
for i := 1 to count do
|
||||
|
||||
sum := sum + bet[i] * i;
|
||||
|
||||
writeln(sum);
|
||||
|
||||
end.
|
||||
82
src/pascal/2023/day8/part1.pas
Normal file
82
src/pascal/2023/day8/part1.pas
Normal file
@@ -0,0 +1,82 @@
|
||||
program day8part1;
|
||||
uses sysutils;
|
||||
|
||||
type
|
||||
MState = (ReadCards, ReadBet);
|
||||
|
||||
var
|
||||
file_: text;
|
||||
|
||||
instructions: AnsiString;
|
||||
str: string;
|
||||
|
||||
count: int32;
|
||||
|
||||
steps: int32;
|
||||
step: char;
|
||||
|
||||
i: int32;
|
||||
|
||||
{ node, left, right }
|
||||
nodes: array[0..1000, 0..2] of string;
|
||||
|
||||
begin
|
||||
{ open inp.txt for reading }
|
||||
assign(file_, 'resources/2023/day8.txt');
|
||||
reset(file_);
|
||||
|
||||
{ read instructions }
|
||||
readln(file_, instructions);
|
||||
|
||||
{ read empty line }
|
||||
readln(file_, str);
|
||||
|
||||
count := 0;
|
||||
|
||||
{ read nodes }
|
||||
while not EOF(file_) do
|
||||
begin
|
||||
|
||||
readln(file_, str);
|
||||
|
||||
{ start }
|
||||
nodes[count, 0] := copy(str, 1, 3);
|
||||
{ left }
|
||||
nodes[count, 1] := copy(str, 8, 3);
|
||||
{ right }
|
||||
nodes[count, 2] := copy(str, 13, 3);
|
||||
|
||||
count := count + 1;
|
||||
|
||||
end;
|
||||
|
||||
{ start at AAA }
|
||||
steps := 0;
|
||||
str := 'AAA';
|
||||
|
||||
{ until we reach the end }
|
||||
while CompareText(str, 'ZZZ') <> 0 do
|
||||
begin
|
||||
|
||||
{ get step }
|
||||
step := instructions[(steps mod length(instructions)) + 1];
|
||||
steps := steps + 1;
|
||||
|
||||
{ find node }
|
||||
for i := 0 to count do
|
||||
begin
|
||||
if CompareText(nodes[i, 0], str) = 0 then
|
||||
break
|
||||
end;
|
||||
|
||||
{ go to next node}
|
||||
case step of
|
||||
'L': str := nodes[i, 1];
|
||||
'R': str := nodes[i, 2];
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
writeln(steps);
|
||||
end.
|
||||
|
||||
184
src/pascal/2023/day8/part2.pas
Normal file
184
src/pascal/2023/day8/part2.pas
Normal file
@@ -0,0 +1,184 @@
|
||||
program day8part2;
|
||||
uses sysutils;
|
||||
|
||||
|
||||
var
|
||||
file_: text;
|
||||
|
||||
instructions: AnsiString;
|
||||
str: string;
|
||||
|
||||
count: int32;
|
||||
|
||||
steps: int32;
|
||||
step: char;
|
||||
|
||||
i, j: int32;
|
||||
|
||||
{ node, left, right }
|
||||
nodes: array[0..1000, 0..2] of string;
|
||||
|
||||
prev_states: array[0..100000] of string;
|
||||
prev_ics: array[0..100000] of int32;
|
||||
prev_count: int32;
|
||||
|
||||
b: array[0..1000] of int32;
|
||||
l: array[0..1000] of int32;
|
||||
a: array[0..1000, 0..1000] of int32;
|
||||
a_count: array[0..1000] of int32;
|
||||
|
||||
current_nodes: array[0..1000] of string;
|
||||
current_nodes_count: int32;
|
||||
|
||||
finished: boolean;
|
||||
|
||||
begin
|
||||
{ open inp.txt for reading }
|
||||
assign(file_, 'resources/2023/day8.txt');
|
||||
reset(file_);
|
||||
|
||||
{ read instructions }
|
||||
readln(file_, instructions);
|
||||
|
||||
{ read empty line }
|
||||
readln(file_, str);
|
||||
|
||||
count := 0;
|
||||
|
||||
{ read nodes }
|
||||
while not EOF(file_) do
|
||||
begin
|
||||
|
||||
readln(file_, str);
|
||||
|
||||
{ start }
|
||||
nodes[count, 0] := copy(str, 1, 3);
|
||||
{ left }
|
||||
nodes[count, 1] := copy(str, 8, 3);
|
||||
{ right }
|
||||
nodes[count, 2] := copy(str, 13, 3);
|
||||
|
||||
count := count + 1;
|
||||
|
||||
end;
|
||||
|
||||
current_nodes_count := 0;
|
||||
|
||||
{ find all nodes that end with A }
|
||||
for i := 0 to count - 1 do
|
||||
begin
|
||||
{ if ends with A }
|
||||
if nodes[i, 0][3] = 'A' then
|
||||
begin
|
||||
{ adds it to current nodes }
|
||||
current_nodes[current_nodes_count] := nodes[i, 0];
|
||||
current_nodes_count := current_nodes_count + 1;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
{ for each node }
|
||||
|
||||
for j := 0 to current_nodes_count - 1 do
|
||||
begin
|
||||
|
||||
steps := 0;
|
||||
prev_count := 0;
|
||||
finished := False;
|
||||
|
||||
writeln(current_nodes[j]);
|
||||
|
||||
while not finished do
|
||||
begin
|
||||
|
||||
{ add state }
|
||||
prev_states[prev_count] := current_nodes[j];
|
||||
prev_ics[prev_count] := (steps mod length(instructions)) + 1;
|
||||
|
||||
{ get step }
|
||||
step := instructions[(steps mod length(instructions)) + 1];
|
||||
steps := steps + 1;
|
||||
|
||||
{ find node }
|
||||
for i := 0 to count do
|
||||
begin
|
||||
if CompareText(nodes[i, 0], current_nodes[j]) = 0 then
|
||||
break
|
||||
end;
|
||||
|
||||
{ go to next node }
|
||||
case step of
|
||||
'L': current_nodes[j] := nodes[i, 1];
|
||||
'R': current_nodes[j] := nodes[i, 2];
|
||||
end;
|
||||
|
||||
{ check if next node is in previous state }
|
||||
for i := 0 to prev_count do
|
||||
begin
|
||||
if (prev_states[i] = current_nodes[j]) and (prev_ics[i] = (steps mod length(instructions)) + 1) then
|
||||
begin
|
||||
finished := true;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
|
||||
prev_count := prev_count + 1;
|
||||
|
||||
end;
|
||||
|
||||
{ offset to start of loop }
|
||||
write('b = ');
|
||||
b[j] := i - 1;
|
||||
writeln(b[j]);
|
||||
|
||||
{ length of loop }
|
||||
write('l = ');
|
||||
l[j] := prev_count - i;
|
||||
writeln(l[j]);
|
||||
|
||||
{ find offsets to the loop where it's finished }
|
||||
a_count[j] := 0;
|
||||
|
||||
for i := b[j] to prev_count - 1 do
|
||||
begin
|
||||
|
||||
{ i'm sure this will cause no problems }
|
||||
if i < 0 then
|
||||
continue;
|
||||
|
||||
{ if this is a finished state }
|
||||
if prev_states[i][3] = 'Z' then
|
||||
begin
|
||||
|
||||
{ add it to the a list }
|
||||
a[j, a_count[j]] := i - b[j];
|
||||
|
||||
write('a_');
|
||||
write(a_count[j]);
|
||||
write(' = ');
|
||||
writeln(a[j, a_count[j]]);
|
||||
|
||||
a_count[j] := a_count[j] + 1;
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
// O( n * (l + b))
|
||||
// l is length of loop
|
||||
// b is length of leadup
|
||||
// n is number of nodes
|
||||
|
||||
// O(a^n)
|
||||
// a is number of finished states
|
||||
|
||||
{
|
||||
|
||||
i might come back to this to actually do this i'm tired rn
|
||||
|
||||
}
|
||||
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
514
src/pascal/2023/day9/bigint.pas
Normal file
514
src/pascal/2023/day9/bigint.pas
Normal file
@@ -0,0 +1,514 @@
|
||||
const
|
||||
UINT32MAX: uint64 = $00000000FFFFFFFF;
|
||||
type
|
||||
int512 = record
|
||||
{ 16 32 bit values in 64 bit ints }
|
||||
values: array[0..15] of int64;
|
||||
end;
|
||||
|
||||
|
||||
operator := (n: int64) b: int512;
|
||||
begin
|
||||
if n >= 0 then
|
||||
fillqword(b.values, 16, 0)
|
||||
else
|
||||
fillqword(b.values, 16, UINT32MAX);
|
||||
b.values[0] := n and UINT32MAX;
|
||||
b.values[1] := n shr 32;
|
||||
end;
|
||||
|
||||
procedure print512(n: int512; printall: boolean = false);
|
||||
var
|
||||
i: int32;
|
||||
started: boolean;
|
||||
begin
|
||||
|
||||
started := printall;
|
||||
|
||||
for i := 0 to 15 do
|
||||
begin
|
||||
if (n.values[15 - i] <> 0) or started or (i = 15) then
|
||||
begin
|
||||
write(hexstr(n.values[15 - i], 8));
|
||||
if (i <> 15) then
|
||||
write(' ');
|
||||
started := true;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure print512f(n: int512; printall: boolean = false);
|
||||
var
|
||||
i: int32;
|
||||
started: boolean;
|
||||
begin
|
||||
|
||||
started := printall;
|
||||
|
||||
for i := 0 to 15 do
|
||||
begin
|
||||
if (n.values[15 - i] <> 0) or started or (i = 15) then
|
||||
begin
|
||||
write(hexstr(n.values[15 - i], 16));
|
||||
if (i <> 15) then
|
||||
write(' ');
|
||||
started := true;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function isneg(n: int512): boolean;
|
||||
begin
|
||||
isneg := (n.values[15] and (1 shl 31)) <> 0
|
||||
end;
|
||||
|
||||
function bigshiftleft(n: int512; b: int32): int512;
|
||||
var
|
||||
i: int32;
|
||||
begin
|
||||
|
||||
bigshiftleft := 0;
|
||||
|
||||
for i := 0 to 15 - b do
|
||||
begin
|
||||
bigshiftleft.values[i + b] := n.values[i];
|
||||
end;
|
||||
end;
|
||||
|
||||
function bigshiftright(n: int512; b: int32): int512;
|
||||
var
|
||||
i: int32;
|
||||
begin
|
||||
|
||||
bigshiftright := 0;
|
||||
|
||||
for i := 0 to 15 - b do
|
||||
begin
|
||||
bigshiftright.values[i] := n.values[i + b];
|
||||
end;
|
||||
end;
|
||||
|
||||
operator shl (a: int512; b: int32) o: int512;
|
||||
var
|
||||
i: int32;
|
||||
begin
|
||||
|
||||
a := bigshiftleft(a, (b and (not 31)) shr 5);
|
||||
|
||||
{ handle first seperately }
|
||||
o.values[0] := (a.values[0] shl (b and 31)) and UINT32MAX;
|
||||
for i := 1 to 15 do
|
||||
begin
|
||||
o.values[i] := (((a.values[i - 1] shl (b and 31)) shr 32) or // leftover from behind cell
|
||||
((a.values[i] shl (b and 31)))) and UINT32MAX; // from this cell
|
||||
end;
|
||||
end;
|
||||
|
||||
operator shr (a: int512; b: int32) o: int512;
|
||||
var
|
||||
i: int32;
|
||||
begin
|
||||
|
||||
a := bigshiftright(a, (b and (not 31)) shr 5);
|
||||
|
||||
{
|
||||
00001234 00005678 00001234
|
||||
12340000 56780000 12340000
|
||||
00000012 00003456 00007812
|
||||
|
||||
}
|
||||
|
||||
for i := 0 to 14 do
|
||||
begin
|
||||
o.values[i] := (((a.values[i + 1] shl (32 - (b and 31))) and UINT32MAX) or // from previous cell
|
||||
(a.values[i] shr (b and 31))) // from this cell
|
||||
end;
|
||||
|
||||
{ handle last seperately }
|
||||
o.values[15] := a.values[15] shr (b and 31);
|
||||
end;
|
||||
|
||||
operator + (a, b: int512) out_: int512;
|
||||
var
|
||||
i: int32;
|
||||
t: int64;
|
||||
carry: int32;
|
||||
begin
|
||||
|
||||
carry := 0;
|
||||
|
||||
for i := 0 to 15 do
|
||||
begin
|
||||
t := a.values[i] + b.values[i] + carry;
|
||||
carry := 0;
|
||||
|
||||
if t > UINT32MAX then
|
||||
begin
|
||||
carry := t shr 32;
|
||||
t := t and UINT32MAX;
|
||||
end;
|
||||
|
||||
out_.values[i] := t;
|
||||
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
operator - (a: int512) out_: int512;
|
||||
var
|
||||
i: int32;
|
||||
begin
|
||||
for i := 0 to 15 do
|
||||
begin
|
||||
a.values[i] := a.values[i] xor UINT32MAX;
|
||||
end;
|
||||
|
||||
out_ := a + 1;
|
||||
end;
|
||||
|
||||
operator - (a, b: int512) out_: int512;
|
||||
begin
|
||||
out_ := a + (- b);
|
||||
end;
|
||||
|
||||
operator > (a, b: int512) out_: boolean;
|
||||
var
|
||||
i: int32;
|
||||
begin
|
||||
|
||||
out_ := false;
|
||||
|
||||
for i := 0 to 15 do
|
||||
begin
|
||||
|
||||
if (a.values[15 - i] > b.values[15 - i]) then
|
||||
begin
|
||||
out_ := true;
|
||||
break;
|
||||
end
|
||||
else if (a.values[15 - i] = b.values[15 - i]) then
|
||||
continue
|
||||
else
|
||||
break
|
||||
end;
|
||||
end;
|
||||
|
||||
operator < (a, b: int512) out_: boolean;
|
||||
var
|
||||
i: int32;
|
||||
begin
|
||||
|
||||
out_ := false;
|
||||
|
||||
for i := 0 to 15 do
|
||||
begin
|
||||
|
||||
if (a.values[15 - i] < b.values[15 - i]) then
|
||||
begin
|
||||
out_ := true;
|
||||
break;
|
||||
end
|
||||
else if (a.values[15 - i] = b.values[15 - i]) then
|
||||
continue
|
||||
else
|
||||
break
|
||||
end;
|
||||
end;
|
||||
|
||||
operator >= (a, b: int512) out_: boolean;
|
||||
begin
|
||||
out_ := not (a < b);
|
||||
end;
|
||||
|
||||
operator <= (a, b: int512) out_: boolean;
|
||||
begin
|
||||
out_ := not (a > b);
|
||||
end;
|
||||
|
||||
operator = (a, b: int512) out_: boolean;
|
||||
var
|
||||
i: int32;
|
||||
begin
|
||||
|
||||
out_ := true;
|
||||
|
||||
for i := 0 to 15 do
|
||||
begin
|
||||
if (a.values[15 - i] = b.values[15 - i]) then
|
||||
continue
|
||||
else
|
||||
begin
|
||||
out_ := false;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
operator <> (a, b: int512) out_: boolean;
|
||||
begin
|
||||
out_ := not (a = b);
|
||||
end;
|
||||
|
||||
operator * (a, b: int512) out_: int512;
|
||||
var
|
||||
|
||||
i, j: int32;
|
||||
t: uint64;
|
||||
carry: int512;
|
||||
neg: boolean;
|
||||
|
||||
begin
|
||||
|
||||
neg := false;
|
||||
if isneg(a) then
|
||||
begin
|
||||
neg := not neg;
|
||||
a := -a;
|
||||
end;
|
||||
|
||||
if isneg(b) then
|
||||
begin
|
||||
neg := not neg;
|
||||
b := -b;
|
||||
end;
|
||||
|
||||
carry := 0;
|
||||
out_ := 0;
|
||||
|
||||
for i := 0 to 15 do
|
||||
begin
|
||||
for j := 0 to 15 do
|
||||
begin
|
||||
if (i + j > 15) then
|
||||
continue;
|
||||
|
||||
t := a.values[i] * b.values[j];
|
||||
|
||||
if t > UINT32MAX then
|
||||
begin
|
||||
carry.values[i + j + 1] := carry.values[i + j + 1] + (t shr 32);
|
||||
t := t and UINT32MAX;
|
||||
end;
|
||||
|
||||
out_.values[i + j] := out_.values[i + j] + t;
|
||||
end;
|
||||
end;
|
||||
|
||||
out_ := carry + out_;
|
||||
|
||||
if neg then
|
||||
out_ := -out_;
|
||||
|
||||
end;
|
||||
|
||||
|
||||
operator mod (a, b: int512) out_: int512;
|
||||
var
|
||||
|
||||
i: int32;
|
||||
normalize_factor: int32;
|
||||
|
||||
begin
|
||||
|
||||
{ normalize divisor }
|
||||
|
||||
{ big normalize }
|
||||
for i := 0 to 15 do
|
||||
begin
|
||||
if b.values[15 - i] <> 0 then
|
||||
begin
|
||||
normalize_factor := i * 32;
|
||||
b := bigshiftleft(b, i);
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
{ small normalize }
|
||||
for i := 0 to 31 do
|
||||
begin
|
||||
if (b.values[15] and (1 shl (31 - i))) <> 0 then
|
||||
begin
|
||||
normalize_factor := normalize_factor + i;
|
||||
b := b shl i;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
|
||||
{subtract}
|
||||
|
||||
for i := 0 to (normalize_factor) do
|
||||
begin
|
||||
|
||||
if a >= b then
|
||||
begin
|
||||
//print512f(a);
|
||||
//write('a ');
|
||||
//print512f(b);
|
||||
//write('b ');
|
||||
//writeln();
|
||||
a := a - b;
|
||||
// only necessary for true division
|
||||
// out_ := out_ + 1;
|
||||
// out_ := out_ shl 1;
|
||||
end;
|
||||
|
||||
b := b shr 1;
|
||||
end;
|
||||
|
||||
out_ := a;
|
||||
end;
|
||||
|
||||
operator div (a, b: int512) out_: int512;
|
||||
var
|
||||
|
||||
i: int32;
|
||||
normalize_factor: int32;
|
||||
neg: boolean;
|
||||
|
||||
begin
|
||||
|
||||
neg := false;
|
||||
if isneg(a) then
|
||||
begin
|
||||
neg := not neg;
|
||||
a := -a;
|
||||
end;
|
||||
|
||||
if isneg(b) then
|
||||
begin
|
||||
neg := not neg;
|
||||
b := -b;
|
||||
end;
|
||||
|
||||
{ normalize divisor }
|
||||
|
||||
{ big normalize }
|
||||
for i := 0 to 15 do
|
||||
begin
|
||||
if b.values[15 - i] <> 0 then
|
||||
begin
|
||||
normalize_factor := i * 32;
|
||||
b := bigshiftleft(b, i);
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ small normalize }
|
||||
for i := 0 to 31 do
|
||||
begin
|
||||
if (b.values[15] and (1 shl (31 - i))) <> 0 then
|
||||
begin
|
||||
normalize_factor := normalize_factor + i;
|
||||
b := b shl i;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
|
||||
{subtract}
|
||||
|
||||
out_ := 0;
|
||||
|
||||
for i := 0 to (normalize_factor) do
|
||||
begin
|
||||
|
||||
out_ := out_ shl 1;
|
||||
|
||||
if a >= b then
|
||||
begin
|
||||
|
||||
{print512f(a);
|
||||
write('a ');
|
||||
print512f(b);
|
||||
write('b ');
|
||||
print512f(out_);
|
||||
write('o ');
|
||||
print512f(out_ shl 1);
|
||||
writeln('o ');}
|
||||
|
||||
a := a - b;
|
||||
|
||||
out_ := out_ + 1;
|
||||
end;
|
||||
|
||||
b := b shr 1;
|
||||
end;
|
||||
|
||||
if neg then
|
||||
out_ := -out_;
|
||||
|
||||
end;
|
||||
|
||||
procedure print512d(n: int512);
|
||||
var
|
||||
c: array[0..1000] of char;
|
||||
count: int32;
|
||||
q: int32;
|
||||
begin
|
||||
|
||||
if isneg(n) then
|
||||
begin
|
||||
write('-');
|
||||
n := -n;
|
||||
end;
|
||||
|
||||
if n = 0 then
|
||||
write('0')
|
||||
else
|
||||
begin
|
||||
count := 0;
|
||||
while n <> 0 do
|
||||
begin
|
||||
c[count] := chr(byte((n mod 10).values[0]) + 48);
|
||||
n := n div 10;
|
||||
count := count + 1;
|
||||
end;
|
||||
|
||||
for q := 1 to count do
|
||||
begin
|
||||
write(c[count - q]);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function abs(n: int512): int512;
|
||||
begin
|
||||
abs := n;
|
||||
if isneg(n) then
|
||||
abs := -n;
|
||||
end;
|
||||
|
||||
function power(n: int512; m: int32): int512;
|
||||
var
|
||||
i: int32;
|
||||
begin
|
||||
power := 1;
|
||||
for i := 1 to m do
|
||||
begin
|
||||
power := power * n;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
// testing
|
||||
{
|
||||
|
||||
var
|
||||
a, b, c: int512;
|
||||
begin
|
||||
b := $1111;
|
||||
a := $FFFFFFFFFFFFFFFF;
|
||||
c := $3000000000000003;
|
||||
|
||||
a := a shl 72 + 1;
|
||||
|
||||
print512(a);
|
||||
writeln();
|
||||
print512(b);
|
||||
writeln();
|
||||
print512(a div b);
|
||||
// 0f000f00 0f000f00 00000000 00000000
|
||||
end.
|
||||
|
||||
}
|
||||
131
src/pascal/2023/day9/fraction.pas
Normal file
131
src/pascal/2023/day9/fraction.pas
Normal file
@@ -0,0 +1,131 @@
|
||||
|
||||
{$include bigint.pas}
|
||||
|
||||
type
|
||||
fraction = record
|
||||
numerator: int512;
|
||||
denominator: int512;
|
||||
end;
|
||||
|
||||
const
|
||||
{ i don't think there's a better way of doing this unfortunately }
|
||||
SIMPLIFY_CUTOFF: int512 = (
|
||||
values: ($00000000FFFFFFFF, $00000000FFFFFFFF, $00000000FFFFFFFF, $00000000FFFFFFFF, $00000000FFFFFFFF, $00000000FFFFFFFF, $00000000FFFFFFFF, $0000000000000000,
|
||||
$0000000000000000, $0000000000000000, $0000000000000000, $0000000000000000, $0000000000000000, $0000000000000000, $0000000000000000, $0000000000000000);
|
||||
);
|
||||
|
||||
procedure print_fraction(a: fraction);
|
||||
begin
|
||||
if a.denominator <> 1 then
|
||||
begin
|
||||
print512d(a.numerator);
|
||||
write('/');
|
||||
print512d(a.denominator);
|
||||
end
|
||||
else
|
||||
print512d(a.numerator);
|
||||
end;
|
||||
|
||||
function c_fraction(num: int512; den: int512): fraction;
|
||||
begin
|
||||
if den = 0 then
|
||||
writeln('holy hell what are you doing');
|
||||
|
||||
c_fraction.numerator := num;
|
||||
c_fraction.denominator := den;
|
||||
|
||||
end;
|
||||
|
||||
operator := (f: int64) out_ : fraction;
|
||||
begin
|
||||
out_ := c_fraction(f, 1);
|
||||
end;
|
||||
|
||||
|
||||
function gcd(a, b: int512): int512;
|
||||
var
|
||||
r: int512;
|
||||
begin
|
||||
|
||||
while true do
|
||||
begin
|
||||
|
||||
r := a mod b;
|
||||
|
||||
if r = 0 then
|
||||
break;
|
||||
|
||||
a := b;
|
||||
b := r;
|
||||
|
||||
end;
|
||||
|
||||
gcd := b;
|
||||
end;
|
||||
|
||||
function simplify(f: fraction): fraction;
|
||||
var
|
||||
b: int512;
|
||||
neg: boolean;
|
||||
|
||||
begin
|
||||
|
||||
neg := false;
|
||||
if isneg(f.numerator) then
|
||||
begin
|
||||
neg := not neg;
|
||||
f.numerator := -f.numerator;
|
||||
end;
|
||||
|
||||
if isneg(f.denominator) then
|
||||
begin
|
||||
neg := not neg;
|
||||
f.denominator := -f.denominator;
|
||||
end;
|
||||
|
||||
b := gcd(f.numerator, f.denominator);
|
||||
|
||||
if b <> 0 then
|
||||
simplify := c_fraction(f.numerator div b, f.denominator div b)
|
||||
else
|
||||
simplify := f;
|
||||
|
||||
if neg then
|
||||
simplify.numerator := -simplify.numerator;
|
||||
|
||||
end;
|
||||
|
||||
{ add fractions }
|
||||
operator + (a, b: fraction) out_: fraction;
|
||||
//var
|
||||
// g: int512;
|
||||
begin
|
||||
|
||||
// print_fraction(a);
|
||||
// write(' ');
|
||||
// print_fraction(b);
|
||||
// write(' ');
|
||||
|
||||
// g := gcd(a.denominator, b.denominator);
|
||||
|
||||
out_.denominator := a.denominator * b.denominator;
|
||||
out_.numerator := a.denominator * b.numerator + b.denominator * a.numerator;
|
||||
|
||||
// print_fraction(out_);
|
||||
// write(' ');
|
||||
if abs(out_.numerator) > SIMPLIFY_CUTOFF then
|
||||
out_ := simplify(out_);
|
||||
// print_fraction(out_);
|
||||
// writeln('ya');
|
||||
end;
|
||||
|
||||
{ mult fractions }
|
||||
operator * (a, b: fraction) out_: fraction;
|
||||
begin
|
||||
out_.denominator := a.denominator * b.denominator;
|
||||
out_.numerator := a.numerator * b.numerator;
|
||||
|
||||
if abs(out_.numerator) > SIMPLIFY_CUTOFF then
|
||||
out_ := simplify(out_);
|
||||
|
||||
end;
|
||||
120
src/pascal/2023/day9/part1.pas
Normal file
120
src/pascal/2023/day9/part1.pas
Normal file
@@ -0,0 +1,120 @@
|
||||
program day9part1;
|
||||
{$INCLUDE 'polynomial.pas'}
|
||||
|
||||
function lagrange(x, y: array of int64; l: int64 = 0): polynomial;
|
||||
var
|
||||
|
||||
new: polynomial;
|
||||
idx: int64;
|
||||
i: int64;
|
||||
|
||||
begin
|
||||
lagrange := constant(c_fraction(0, 1));
|
||||
|
||||
if l = 0 then
|
||||
begin
|
||||
case length(x) > length(y) of
|
||||
true: l := length(y);
|
||||
false: l := length(x);
|
||||
end;
|
||||
end;
|
||||
|
||||
for idx := 0 to l - 1 do
|
||||
begin
|
||||
|
||||
new := constant(c_fraction((y[idx]), 1));
|
||||
|
||||
for i := 0 to l - 1 do
|
||||
begin
|
||||
if i = idx then
|
||||
continue;
|
||||
|
||||
new := new * binomial(c_fraction(1, 1), c_fraction(- x[i], 1));
|
||||
|
||||
new := new * constant(c_fraction(1, (x[idx] - x[i])));
|
||||
|
||||
end;
|
||||
|
||||
lagrange := lagrange + new;
|
||||
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
|
||||
var
|
||||
|
||||
{ couldn't have done that with a for loop }
|
||||
x: array[0..100] of int64 = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100);
|
||||
y: array[0..100] of int64;
|
||||
|
||||
file_: text;
|
||||
str: string;
|
||||
negative, number: int64;
|
||||
|
||||
c: char;
|
||||
|
||||
count, b: int64;
|
||||
|
||||
sum: fraction;
|
||||
p: polynomial;
|
||||
f: fraction;
|
||||
|
||||
begin
|
||||
|
||||
assign(file_, 'resources/2023/day9.txt');
|
||||
reset(file_);
|
||||
|
||||
sum := c_fraction(0, 1);
|
||||
|
||||
while not EOF(file_) do
|
||||
begin
|
||||
|
||||
readln(file_, str);
|
||||
count := 0;
|
||||
number := 0;
|
||||
negative := 1;
|
||||
|
||||
for c in str do
|
||||
begin
|
||||
if c = '-' then
|
||||
negative := -1
|
||||
else if (('0' <= c) and (c <= '9')) then
|
||||
begin
|
||||
//add number to number
|
||||
val(c, b);
|
||||
number := number * 10 + b;
|
||||
end
|
||||
else
|
||||
begin
|
||||
y[count] := number * negative;
|
||||
count := count + 1;
|
||||
number := 0;
|
||||
negative := 1;
|
||||
end;
|
||||
end;
|
||||
|
||||
y[count] := number * negative;
|
||||
|
||||
p := simplify_poly(lagrange(x, y, count + 1));
|
||||
|
||||
print_polynomial(p);
|
||||
write(' at ');
|
||||
write(count + 1);
|
||||
write(' is ');
|
||||
|
||||
f := simplify(eval_polynomial(p, count + 1));
|
||||
|
||||
print_fraction(f);
|
||||
|
||||
sum := sum + f;
|
||||
|
||||
writeln();
|
||||
|
||||
end;
|
||||
|
||||
write('The final sum is: ');
|
||||
|
||||
print_fraction(sum);
|
||||
|
||||
end.
|
||||
120
src/pascal/2023/day9/part2.pas
Normal file
120
src/pascal/2023/day9/part2.pas
Normal file
@@ -0,0 +1,120 @@
|
||||
program day9part1;
|
||||
{$INCLUDE 'polynomial.pas'}
|
||||
|
||||
function lagrange(x, y: array of int64; l: int64 = 0): polynomial;
|
||||
var
|
||||
|
||||
new: polynomial;
|
||||
idx: int64;
|
||||
i: int64;
|
||||
|
||||
begin
|
||||
lagrange := constant(c_fraction(0, 1));
|
||||
|
||||
if l = 0 then
|
||||
begin
|
||||
case length(x) > length(y) of
|
||||
true: l := length(y);
|
||||
false: l := length(x);
|
||||
end;
|
||||
end;
|
||||
|
||||
for idx := 0 to l - 1 do
|
||||
begin
|
||||
|
||||
new := constant(c_fraction((y[idx]), 1));
|
||||
|
||||
for i := 0 to l - 1 do
|
||||
begin
|
||||
if i = idx then
|
||||
continue;
|
||||
|
||||
new := new * binomial(c_fraction(1, 1), c_fraction(- x[i], 1));
|
||||
|
||||
new := new * constant(c_fraction(1, (x[idx] - x[i])));
|
||||
|
||||
end;
|
||||
|
||||
lagrange := lagrange + new;
|
||||
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
|
||||
var
|
||||
|
||||
{ couldn't have done that with a for loop }
|
||||
x: array[0..100] of int64 = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100);
|
||||
y: array[0..100] of int64;
|
||||
|
||||
file_: text;
|
||||
str: string;
|
||||
negative, number: int64;
|
||||
|
||||
c: char;
|
||||
|
||||
count, b: int64;
|
||||
|
||||
sum: fraction;
|
||||
p: polynomial;
|
||||
f: fraction;
|
||||
|
||||
begin
|
||||
|
||||
assign(file_, 'resources/2023/day9.txt');
|
||||
reset(file_);
|
||||
|
||||
sum := c_fraction(0, 1);
|
||||
|
||||
while not EOF(file_) do
|
||||
begin
|
||||
|
||||
readln(file_, str);
|
||||
count := 0;
|
||||
number := 0;
|
||||
negative := 1;
|
||||
|
||||
for c in str do
|
||||
begin
|
||||
if c = '-' then
|
||||
negative := -1
|
||||
else if (('0' <= c) and (c <= '9')) then
|
||||
begin
|
||||
//add number to number
|
||||
val(c, b);
|
||||
number := number * 10 + b;
|
||||
end
|
||||
else
|
||||
begin
|
||||
y[count] := number * negative;
|
||||
count := count + 1;
|
||||
number := 0;
|
||||
negative := 1;
|
||||
end;
|
||||
end;
|
||||
|
||||
y[count] := number * negative;
|
||||
|
||||
p := simplify_poly(lagrange(x, y, count + 1));
|
||||
|
||||
print_polynomial(p);
|
||||
write(' at ');
|
||||
write(-1);
|
||||
write(' is ');
|
||||
|
||||
f := simplify(eval_polynomial(p, -1));
|
||||
|
||||
print_fraction(f);
|
||||
|
||||
sum := sum + f;
|
||||
|
||||
writeln();
|
||||
|
||||
end;
|
||||
|
||||
write('The final sum is: ');
|
||||
|
||||
print_fraction(sum);
|
||||
|
||||
end.
|
||||
170
src/pascal/2023/day9/polynomial.pas
Normal file
170
src/pascal/2023/day9/polynomial.pas
Normal file
@@ -0,0 +1,170 @@
|
||||
{$mode objfpc}
|
||||
|
||||
uses sysutils, math;
|
||||
|
||||
{$include fraction.pas}
|
||||
|
||||
const
|
||||
MAX_POLYNOMIAL_LENGTH = 100;
|
||||
|
||||
type
|
||||
polynomial = record
|
||||
degree: int64;
|
||||
{ coefficients will be stored in reverse. ofc}
|
||||
coefficients: array[0..MAX_POLYNOMIAL_LENGTH] of fraction;
|
||||
end;
|
||||
|
||||
|
||||
procedure fill_array_1(var a: array of fraction; l: int64 = MAX_POLYNOMIAL_LENGTH);
|
||||
var
|
||||
i: int64;
|
||||
begin
|
||||
|
||||
for i := 0 to l do
|
||||
a[i] := c_fraction(0, 1);
|
||||
|
||||
end;
|
||||
|
||||
{ add polynomials }
|
||||
operator + (a, b: polynomial) add_polynomial: polynomial;
|
||||
var
|
||||
|
||||
new_degree: int64;
|
||||
max_degree: int64;
|
||||
i: int64;
|
||||
|
||||
begin
|
||||
|
||||
case a.degree > b.degree of
|
||||
true: max_degree := a.degree;
|
||||
false: max_degree := b.degree;
|
||||
end;
|
||||
|
||||
fill_array_1(add_polynomial.coefficients);
|
||||
|
||||
for i := 0 to max_degree do
|
||||
begin
|
||||
add_polynomial.coefficients[i] := a.coefficients[i] + b.coefficients[i];
|
||||
|
||||
if add_polynomial.coefficients[i].numerator <> 0 then
|
||||
new_degree := i
|
||||
end;
|
||||
|
||||
add_polynomial.degree := new_degree;
|
||||
end;
|
||||
|
||||
{ mult polynomials }
|
||||
operator * (a, b: polynomial) out_: polynomial;
|
||||
var
|
||||
|
||||
i, j: int64;
|
||||
new_degree: int32;
|
||||
|
||||
begin
|
||||
|
||||
out_.degree := a.degree + b.degree;
|
||||
|
||||
fill_array_1(out_.coefficients);
|
||||
|
||||
for i := 0 to a.degree do
|
||||
begin
|
||||
for j := 0 to b.degree do
|
||||
begin
|
||||
|
||||
out_.coefficients[i + j] := out_.coefficients[i + j] + a.coefficients[i] * b.coefficients[j];
|
||||
|
||||
end;
|
||||
end;
|
||||
|
||||
for i := 0 to out_.degree do
|
||||
begin
|
||||
|
||||
if out_.coefficients[i].numerator <> 0 then
|
||||
new_degree := i
|
||||
end;
|
||||
|
||||
out_.degree := new_degree;
|
||||
|
||||
end;
|
||||
|
||||
function constant(c: fraction): polynomial;
|
||||
begin
|
||||
fill_array_1(constant.coefficients);
|
||||
constant.coefficients[0] := c;
|
||||
constant.degree := 0;
|
||||
end;
|
||||
|
||||
function binomial(m, b: fraction): polynomial;
|
||||
begin
|
||||
fill_array_1(binomial.coefficients);
|
||||
binomial.coefficients[0] := b;
|
||||
binomial.coefficients[1] := m;
|
||||
binomial.degree := 1;
|
||||
end;
|
||||
|
||||
|
||||
function eval_polynomial(a: polynomial; b: int512): fraction;
|
||||
var
|
||||
i: int64;
|
||||
begin
|
||||
|
||||
eval_polynomial := c_fraction(0, 1);
|
||||
|
||||
for i := 0 to a.degree do
|
||||
begin
|
||||
eval_polynomial := eval_polynomial + a.coefficients[i] * c_fraction(power(b, i), 1);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure print_polynomial(a: polynomial);
|
||||
var
|
||||
|
||||
i: int64;
|
||||
|
||||
begin
|
||||
|
||||
for i := 0 to a.degree do
|
||||
begin
|
||||
if (a.coefficients[a.degree - i].numerator <> 0) or (a.degree = 0) then
|
||||
begin
|
||||
if i <> 0 then
|
||||
begin
|
||||
if isneg(a.coefficients[a.degree - i].numerator) then
|
||||
begin
|
||||
a.coefficients[a.degree - i].numerator := -a.coefficients[a.degree - i].numerator;
|
||||
write(' - ');
|
||||
end
|
||||
else
|
||||
write(' + ');
|
||||
end;
|
||||
|
||||
{ yeah. need an equality for fraction. }
|
||||
if (a.coefficients[a.degree - i].numerator <> 1) and (a.coefficients[a.degree - i].denominator <> 1) or (i = a.degree) then
|
||||
print_fraction(a.coefficients[a.degree - i]);
|
||||
|
||||
if i = a.degree - 1 then
|
||||
write('x')
|
||||
else if i < a.degree - 1 then
|
||||
begin
|
||||
write('x^');
|
||||
write(a.degree - i);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
write(' (');
|
||||
write(a.degree);
|
||||
write(')');
|
||||
|
||||
end;
|
||||
|
||||
function simplify_poly(a: polynomial): polynomial;
|
||||
var
|
||||
i: int32;
|
||||
begin
|
||||
for i := 0 to a.degree do
|
||||
begin
|
||||
simplify_poly.coefficients[i] := simplify(a.coefficients[i]);
|
||||
end;
|
||||
simplify_poly.degree := a.degree;
|
||||
end;
|
||||
52
src/pladcl/2023/day1/part2.pdl
Normal file
52
src/pladcl/2023/day1/part2.pdl
Normal file
@@ -0,0 +1,52 @@
|
||||
state search_first
|
||||
parse_int()
|
||||
`z0=q`
|
||||
`ds1s2`
|
||||
set_state(search_second)
|
||||
end
|
||||
|
||||
state search_second
|
||||
parse_int()
|
||||
`z0=q`
|
||||
`s2`
|
||||
end
|
||||
|
||||
interrupt newline
|
||||
`l2l110*+`
|
||||
`lo+so`
|
||||
set_state(search_first)
|
||||
end
|
||||
|
||||
interrupt program_end
|
||||
`lop`
|
||||
end
|
||||
|
||||
function parse_int
|
||||
|
||||
`[`
|
||||
`ln48>qln57<q`
|
||||
`ln48-q`
|
||||
`]x`
|
||||
|
||||
`1`
|
||||
streq(0, "one")
|
||||
`1=q1+`
|
||||
streq(0, "two")
|
||||
`1=q1+`
|
||||
streq(0, "three")
|
||||
`1=q1+`
|
||||
streq(0, "four")
|
||||
`1=q1+`
|
||||
streq(0, "five")
|
||||
`1=q1+`
|
||||
streq(0, "six")
|
||||
`1=q1+`
|
||||
streq(0, "seven")
|
||||
`1=q1+`
|
||||
streq(0, "eight")
|
||||
`1=q1+`
|
||||
streq(0, "nine")
|
||||
`1=q`
|
||||
`s.`
|
||||
|
||||
end
|
||||
144
src/pladcl/2024/day1/part1.pdl
Normal file
144
src/pladcl/2024/day1/part1.pdl
Normal file
@@ -0,0 +1,144 @@
|
||||
state read_first
|
||||
read_number()
|
||||
`S1`
|
||||
set_state(read_second)
|
||||
end
|
||||
|
||||
state read_second
|
||||
return_if(`ln` == 32)
|
||||
read_number()
|
||||
`S2`
|
||||
end
|
||||
|
||||
interrupt newline
|
||||
adjust_index(1)
|
||||
set_state(read_first)
|
||||
end
|
||||
|
||||
interrupt program_start
|
||||
`_1S1`
|
||||
`_1S2`
|
||||
end
|
||||
|
||||
interrupt program_end
|
||||
`L1st` # remove the extra -1
|
||||
|
||||
`_1S3`
|
||||
`_1S4`
|
||||
|
||||
# until we drain 1
|
||||
while `L1ds!` != -1 do
|
||||
|
||||
#`[1)]nf`
|
||||
|
||||
# until we drain 3
|
||||
while `L3ds#` != -1 do
|
||||
# if top of stack is greater than !
|
||||
if `l#` >= `l!` then
|
||||
`l#S3` # push # back onto 3
|
||||
#`[2)]nf`
|
||||
break
|
||||
end
|
||||
|
||||
`l#S1` # push # onto 1
|
||||
#`[3)]nf`
|
||||
|
||||
|
||||
end
|
||||
|
||||
#`[4)]nf`
|
||||
|
||||
# if we popped the end of array off then put it back on
|
||||
if `l#` == -1 then
|
||||
`_1S3`
|
||||
end
|
||||
|
||||
|
||||
`l!S3` # push ! into temp stack
|
||||
|
||||
end
|
||||
|
||||
debug_print("sorted 1")
|
||||
|
||||
# until we drain 2
|
||||
while `L2ds@` != -1 do
|
||||
|
||||
# until we drain 4
|
||||
while `L4ds$` != -1 do
|
||||
# if top of stack is greater than @
|
||||
if `l$` >= `l@` then
|
||||
`l$S4` # push $ back onto 4
|
||||
break
|
||||
end
|
||||
|
||||
`l$S2` # push $ onto 2
|
||||
|
||||
end
|
||||
|
||||
# if we popped the end of array off then put it back on
|
||||
if `l$` == -1 then
|
||||
`_1S4`
|
||||
end
|
||||
|
||||
|
||||
`l@S4` # push @ into temp stack
|
||||
|
||||
end
|
||||
|
||||
`0so`
|
||||
|
||||
debug_print("sorted")
|
||||
|
||||
while `L4s2L3ds1` != -1 do
|
||||
`l1l2-`
|
||||
abs()
|
||||
`lo+so`
|
||||
end
|
||||
|
||||
`lop`
|
||||
|
||||
end
|
||||
|
||||
function read_number
|
||||
read_number_start()
|
||||
read_number_end()
|
||||
end
|
||||
|
||||
function read_number_start
|
||||
|
||||
-1
|
||||
# ret _1 if not a digit
|
||||
return_if(`ln` < 48)
|
||||
return_if(`ln` > 57)
|
||||
`st`
|
||||
|
||||
# throw the true digit onto the stack
|
||||
`ln48-`
|
||||
|
||||
# inc i
|
||||
adjust_index(1)
|
||||
# recurse
|
||||
read_number_start()
|
||||
|
||||
end
|
||||
|
||||
function read_number_end
|
||||
|
||||
# if we only have 1 item on stack (-1) we found no number, so return
|
||||
return_if(1 == `z`)
|
||||
|
||||
# push entire number thing onto temporary stack
|
||||
`[STz0<.]ds.x`
|
||||
# multiply ten then pop and add repeatedly until done
|
||||
`0`
|
||||
`[LTd_1=qr10*+l.x]ds.x`
|
||||
# get rid of the extra -1
|
||||
`st`
|
||||
# decrement i so we reread the skipped char
|
||||
adjust_index(-1)
|
||||
|
||||
end
|
||||
|
||||
function abs
|
||||
`d0<q0r-`
|
||||
end
|
||||
80
src/pladcl/2024/day1/part2.pdl
Normal file
80
src/pladcl/2024/day1/part2.pdl
Normal file
@@ -0,0 +1,80 @@
|
||||
state read_first
|
||||
read_number()
|
||||
`S1`
|
||||
set_state(read_second)
|
||||
end
|
||||
|
||||
state read_second
|
||||
return_if(`ln` == 32)
|
||||
read_number()
|
||||
`d;2` # load current amount
|
||||
`1+` # inc
|
||||
`r:2` # and store
|
||||
end
|
||||
|
||||
interrupt newline
|
||||
adjust_index(1)
|
||||
set_state(read_first)
|
||||
end
|
||||
|
||||
interrupt program_start
|
||||
`_1S1`
|
||||
end
|
||||
|
||||
interrupt program_end
|
||||
|
||||
debug_print("wow")
|
||||
|
||||
# burn off one
|
||||
`L1st`
|
||||
|
||||
while `L1ds!` != -1 do
|
||||
`l!d;2*`
|
||||
`lo+so`
|
||||
end
|
||||
|
||||
`lop`
|
||||
|
||||
end
|
||||
|
||||
function read_number
|
||||
read_number_start()
|
||||
read_number_end()
|
||||
end
|
||||
|
||||
function read_number_start
|
||||
|
||||
-1
|
||||
# ret _1 if not a digit
|
||||
return_if(`ln` < 48)
|
||||
return_if(`ln` > 57)
|
||||
`st`
|
||||
|
||||
# throw the true digit onto the stack
|
||||
`ln48-`
|
||||
|
||||
# inc i
|
||||
adjust_index(1)
|
||||
# recurse
|
||||
read_number_start()
|
||||
|
||||
end
|
||||
|
||||
function read_number_end
|
||||
|
||||
# if we only have 1 item on stack (-1) we found no number, so return
|
||||
return_if(1 == `z`)
|
||||
|
||||
# push entire number thing onto temporary stack
|
||||
`[STz0<.]ds.x`
|
||||
# multiply ten then pop and add repeatedly until done
|
||||
`0`
|
||||
`[LTd_1=qr10*+l.x]ds.x`
|
||||
# get rid of the extra -1
|
||||
`st`
|
||||
# decrement i so we reread the skipped char
|
||||
adjust_index(-1)
|
||||
|
||||
end
|
||||
|
||||
|
||||
153
src/pladcl/2024/day2/part1.pdl
Normal file
153
src/pladcl/2024/day2/part1.pdl
Normal file
@@ -0,0 +1,153 @@
|
||||
state start
|
||||
# read a number and put it into the report stack
|
||||
read_number()
|
||||
`[d_1!=qs.q]x`
|
||||
`SR`
|
||||
end
|
||||
|
||||
# prime the report stack with an end token
|
||||
interrupt program_start
|
||||
`_1SR`
|
||||
end
|
||||
|
||||
interrupt newline
|
||||
|
||||
|
||||
# check sequence and add it into output
|
||||
check_sequence()
|
||||
`lo+so`
|
||||
|
||||
# increment past newline
|
||||
`li1+dsi;Isn`
|
||||
# clear report
|
||||
`_1SR`
|
||||
|
||||
end
|
||||
|
||||
interrupt program_end
|
||||
`lop`
|
||||
end
|
||||
|
||||
function check_sequence
|
||||
|
||||
`[chk]n10an`
|
||||
|
||||
`[s.q]s?`
|
||||
|
||||
# return value
|
||||
`0`
|
||||
|
||||
# start checking the first two values (+1)
|
||||
`LRLRdSR-`
|
||||
|
||||
# return if 0 (0)
|
||||
`d0=?`
|
||||
|
||||
# calc abs, return if > 3 (0)
|
||||
`d`
|
||||
abs()
|
||||
`3<?`
|
||||
|
||||
# if desc
|
||||
`[d0<qs.`
|
||||
check_descending_sequence()
|
||||
`+q]x` # add it's return value to 0
|
||||
|
||||
`[0>q`
|
||||
check_ascending_sequence()
|
||||
`+q]x`
|
||||
|
||||
end
|
||||
|
||||
function check_descending_sequence
|
||||
|
||||
`[dsc]n10an`
|
||||
|
||||
`[s.s.1+q]s!` # success macro
|
||||
`[s.q]s?` # cleanup fail macro
|
||||
|
||||
# ret value
|
||||
|
||||
`0`
|
||||
|
||||
# start with smth
|
||||
`LR`
|
||||
`[`
|
||||
`LRdSR` # grab (and replace the next character)
|
||||
`d_1=!` # if we're done then break out of here as a success
|
||||
`-` # get difference
|
||||
`d_1<?` # if > -1 fail
|
||||
`_3>q` # if < -3 fail
|
||||
`LR` # grab the next
|
||||
`l.x` # and loop
|
||||
`]ds.x`
|
||||
end
|
||||
|
||||
function check_ascending_sequence
|
||||
|
||||
|
||||
`[asc]n10an`
|
||||
|
||||
`[s.s.1+q]s!` # success macro
|
||||
`[s.q]s?` # cleanup fail macro
|
||||
|
||||
# ret value
|
||||
|
||||
`0`
|
||||
|
||||
# start with smth
|
||||
`LR`
|
||||
`[`
|
||||
`LRdSR` # grab (and replace the next character)
|
||||
`d_1=!` # if we're done then break out of here as a success
|
||||
`-` # get difference
|
||||
`d1>?` # if < 1 fail
|
||||
`3<q` # if > 3 fail
|
||||
`LR` # grab the next
|
||||
`l.x` # and loop
|
||||
`]ds.x`
|
||||
|
||||
end
|
||||
|
||||
function read_number
|
||||
read_number_start()
|
||||
read_number_end()
|
||||
end
|
||||
|
||||
function read_number_start
|
||||
`_1`
|
||||
# ret _1 if not a digit
|
||||
`ln48>q`
|
||||
`ln57<q`
|
||||
`s.`
|
||||
|
||||
# throw the true digit onto the stack
|
||||
`ln48-`
|
||||
|
||||
# inc i
|
||||
`li1+dsi;Isn`
|
||||
# recurse
|
||||
read_number_start()
|
||||
|
||||
end
|
||||
|
||||
function read_number_end
|
||||
|
||||
# if we only have 1 item on stack (-1) we found no number, so return
|
||||
`z1=q`
|
||||
|
||||
# push entire number thing onto temporary stack
|
||||
`[STz0<.]ds.x`
|
||||
# multiply ten then pop and add repeatedly until done
|
||||
`0`
|
||||
`[LTd_1=qr10*+l.x]ds.x`
|
||||
# get rid of the extra -1
|
||||
`s.`
|
||||
# decrement i so we reread the skipped char
|
||||
`li1-dsi;Isn`
|
||||
|
||||
end
|
||||
|
||||
function abs
|
||||
`d0<q0r-`
|
||||
end
|
||||
207
src/pladcl/2024/day2/part2.pdl
Normal file
207
src/pladcl/2024/day2/part2.pdl
Normal file
@@ -0,0 +1,207 @@
|
||||
state start
|
||||
# read a number and put it into the report stack
|
||||
read_number()
|
||||
`[d_1!=qs.q]x`
|
||||
`lc:T` # put this into T at c
|
||||
`lc1+sc` #inc c
|
||||
end
|
||||
|
||||
# prime the report stack with an end token
|
||||
interrupt program_start
|
||||
`_1SR`
|
||||
`0sc` # count
|
||||
end
|
||||
|
||||
interrupt newline
|
||||
|
||||
|
||||
# check sequence and add it into output
|
||||
check_all_sequences()
|
||||
`lo+so`
|
||||
|
||||
# increment past newline
|
||||
`li1+dsi;Isn`
|
||||
# reset report size
|
||||
`0sc`
|
||||
|
||||
end
|
||||
|
||||
function check_all_sequences
|
||||
|
||||
# check no edits
|
||||
|
||||
# start at c - 1
|
||||
`lc1-`
|
||||
|
||||
`_1SR` # make sure it ends here
|
||||
|
||||
`[`
|
||||
`d;T` # fetch number
|
||||
`SR` # push into r
|
||||
`1-` # decrement
|
||||
`d_1!=.` # loop if not -1
|
||||
`]ds.x`
|
||||
|
||||
debug(`[hello]n`)
|
||||
|
||||
`s.` # remove junk
|
||||
|
||||
check_sequence() # check sequence
|
||||
|
||||
`[d;TSR]s>` # macro for storing new number
|
||||
|
||||
`lc1-sd` # now we start skipping. starting with the dth
|
||||
|
||||
`[`
|
||||
`_1SR` # make sure to cap report
|
||||
`lc1-` # start of the thing
|
||||
|
||||
`[` # copy loop
|
||||
|
||||
`dld!=>` # copy a number iff index is not d
|
||||
`1-` # decrement index
|
||||
`d_1!=.` # loop if not -1
|
||||
`]ds.x`
|
||||
`s.` # remove junk
|
||||
|
||||
check_sequence() # add in this check sequence to our return
|
||||
`+`
|
||||
|
||||
`ld1-dsd` # decrement d
|
||||
debug(`[d]np`)
|
||||
`_1!=<` # loop if not _1
|
||||
|
||||
`]ds<x`
|
||||
|
||||
`[d1>qs.1]x` # cap to one
|
||||
|
||||
|
||||
end
|
||||
|
||||
interrupt program_end
|
||||
`lop`
|
||||
end
|
||||
|
||||
function check_sequence
|
||||
|
||||
debug(`[chk]n10an`)
|
||||
|
||||
`[s.q]s?`
|
||||
|
||||
# return value
|
||||
`0`
|
||||
|
||||
# start checking the first two values (+1)
|
||||
`LRLRdSR-`
|
||||
|
||||
# return if 0 (0)
|
||||
`d0=?`
|
||||
|
||||
# calc abs, return if > 3 (0)
|
||||
`d`
|
||||
abs()
|
||||
`3<?`
|
||||
|
||||
# if desc
|
||||
`[d0<qs.`
|
||||
check_descending_sequence()
|
||||
`+q]x` # add it's return value to 0
|
||||
|
||||
`[0>q`
|
||||
check_ascending_sequence()
|
||||
`+q]x`
|
||||
|
||||
end
|
||||
|
||||
function check_descending_sequence
|
||||
|
||||
debug(`[dsc]n10an`)
|
||||
|
||||
`[s.s.1+q]s!` # success macro
|
||||
`[s.q]s?` # cleanup fail macro
|
||||
|
||||
# ret value
|
||||
|
||||
`0`
|
||||
|
||||
# start with smth
|
||||
`LR`
|
||||
`[`
|
||||
`LRdSR` # grab (and replace the next character)
|
||||
`d_1=!` # if we're done then break out of here as a success
|
||||
`-` # get difference
|
||||
`d_1<?` # if > -1 fail
|
||||
`_3>q` # if < -3 fail
|
||||
`LR` # grab the next
|
||||
`l.x` # and loop
|
||||
`]ds.x`
|
||||
end
|
||||
|
||||
function check_ascending_sequence
|
||||
|
||||
|
||||
debug(`[asc]n10an`)
|
||||
|
||||
`[s.s.1+q]s!` # success macro
|
||||
`[s.q]s?` # cleanup fail macro
|
||||
|
||||
# ret value
|
||||
|
||||
`0`
|
||||
|
||||
# start with smth
|
||||
`LR`
|
||||
`[`
|
||||
`LRdSR` # grab (and replace the next character)
|
||||
`d_1=!` # if we're done then break out of here as a success
|
||||
`-` # get difference
|
||||
`d1>?` # if < 1 fail
|
||||
`3<q` # if > 3 fail
|
||||
`LR` # grab the next
|
||||
`l.x` # and loop
|
||||
`]ds.x`
|
||||
|
||||
end
|
||||
|
||||
function read_number
|
||||
read_number_start()
|
||||
read_number_end()
|
||||
end
|
||||
|
||||
function read_number_start
|
||||
`_1`
|
||||
# ret _1 if not a digit
|
||||
`ln48>q`
|
||||
`ln57<q`
|
||||
`s.`
|
||||
|
||||
# throw the true digit onto the stack
|
||||
`ln48-`
|
||||
|
||||
# inc i
|
||||
`li1+dsi;Isn`
|
||||
# recurse
|
||||
read_number_start()
|
||||
|
||||
end
|
||||
|
||||
function read_number_end
|
||||
|
||||
# if we only have 1 item on stack (-1) we found no number, so return
|
||||
`z1=q`
|
||||
|
||||
# push entire number thing onto temporary stack
|
||||
`[STz0<.]ds.x`
|
||||
# multiply ten then pop and add repeatedly until done
|
||||
`0`
|
||||
`[LTd_1=qr10*+l.x]ds.x`
|
||||
# get rid of the extra -1
|
||||
`s.`
|
||||
# decrement i so we reread the skipped char
|
||||
`li1-dsi;Isn`
|
||||
|
||||
end
|
||||
|
||||
function abs
|
||||
`d0<q0r-`
|
||||
end
|
||||
100
src/pladcl/2024/day3/part1.pdl
Normal file
100
src/pladcl/2024/day3/part1.pdl
Normal file
@@ -0,0 +1,100 @@
|
||||
interrupt program_start
|
||||
|
||||
`[`
|
||||
set_state(search_mul)
|
||||
`q]s!` # fail subroutine, go back to looking for m
|
||||
|
||||
`0so` # setup output register
|
||||
|
||||
end
|
||||
|
||||
interrupt program_end
|
||||
|
||||
`lop` # lop
|
||||
|
||||
end
|
||||
|
||||
|
||||
state search_mul
|
||||
|
||||
streq(0, "mul(")
|
||||
`0=q` # if not mul( continue
|
||||
`li3+dsi;Isn` # increment i past the string
|
||||
|
||||
set_state(search_first_num) # else get number
|
||||
|
||||
end
|
||||
|
||||
state search_first_num
|
||||
|
||||
read_number()
|
||||
`ds1` # read and store the first number
|
||||
`_1=!` # if it's not a real number go back
|
||||
set_state(search_comma)
|
||||
|
||||
end
|
||||
|
||||
state search_comma
|
||||
|
||||
`ln44!=!` # if not a comma break
|
||||
set_state(search_second_num)
|
||||
|
||||
end
|
||||
|
||||
state search_second_num
|
||||
read_number()
|
||||
`ds2` # read and store the second number
|
||||
`_1=!` # if it' not a number go back
|
||||
set_state(search_end_paren)
|
||||
end
|
||||
|
||||
state search_end_paren
|
||||
`ln41!=!` # if it's not a ")" this instruction sucks
|
||||
|
||||
debug(`[got one]n10an`)
|
||||
|
||||
`l1l2*` # calculate the multiply
|
||||
`lo+so` # add it into output
|
||||
|
||||
set_state(search_mul)
|
||||
|
||||
end
|
||||
|
||||
function read_number
|
||||
read_number_start()
|
||||
read_number_end()
|
||||
end
|
||||
|
||||
function read_number_start
|
||||
`_1`
|
||||
# ret _1 if not a digit
|
||||
`ln48>q`
|
||||
`ln57<q`
|
||||
`s.`
|
||||
|
||||
# throw the true digit onto the stack
|
||||
`ln48-`
|
||||
|
||||
# inc i
|
||||
`li1+dsi;Isn`
|
||||
# recurse
|
||||
read_number_start()
|
||||
|
||||
end
|
||||
|
||||
function read_number_end
|
||||
|
||||
# if we only have 1 item on stack (-1) we found no number, so return
|
||||
`z1=q`
|
||||
|
||||
# push entire number thing onto temporary stack
|
||||
`[STz0<.]ds.x`
|
||||
# multiply ten then pop and add repeatedly until done
|
||||
`0`
|
||||
`[LTd_1=qr10*+l.x]ds.x`
|
||||
# get rid of the extra -1
|
||||
`s.`
|
||||
# decrement i so we reread the skipped char
|
||||
`li1-dsi;Isn`
|
||||
|
||||
end
|
||||
127
src/pladcl/2024/day3/part2.pdl
Normal file
127
src/pladcl/2024/day3/part2.pdl
Normal file
@@ -0,0 +1,127 @@
|
||||
interrupt program_start
|
||||
|
||||
`[`
|
||||
set_state(search_mul)
|
||||
`li1-dsi;Isn` # go back a character -- just in case this was the start of something
|
||||
`q]s!` # fail subroutine, go back to looking for m
|
||||
|
||||
`0so` # setup output register
|
||||
|
||||
`1se` # start enabled
|
||||
|
||||
end
|
||||
|
||||
interrupt program_end
|
||||
|
||||
`lop` # lop
|
||||
|
||||
end
|
||||
|
||||
|
||||
state search_mul
|
||||
|
||||
# check for do()
|
||||
streq(0, "do()")
|
||||
`[0=q` # if not do nothing
|
||||
`1se` # enable
|
||||
`q` # we're done here
|
||||
`]x`
|
||||
|
||||
# check for don't()
|
||||
streq(0, "don't()")
|
||||
`[0=q` # if not do nothing
|
||||
`0se` # disable
|
||||
`q` # we're done here
|
||||
`]x`
|
||||
|
||||
|
||||
streq(0, "mul(")
|
||||
`0=q` # if not mul( continue
|
||||
adjust_index(3) # increment i past the string
|
||||
|
||||
set_state(search_first_num) # else get number
|
||||
|
||||
end
|
||||
|
||||
state search_first_num
|
||||
|
||||
read_number()
|
||||
`ds1` # read and store the first number
|
||||
`_1=!` # if it's not a real number go back
|
||||
set_state(search_comma)
|
||||
|
||||
end
|
||||
|
||||
state search_comma
|
||||
|
||||
`ln44!=!` # if not a comma break
|
||||
set_state(search_second_num)
|
||||
|
||||
end
|
||||
|
||||
state search_second_num
|
||||
read_number()
|
||||
`ds2` # read and store the second number
|
||||
`_1=!` # if it' not a number go back
|
||||
set_state(search_end_paren)
|
||||
end
|
||||
|
||||
state search_end_paren
|
||||
`ln41!=!` # if it's not a ")" this instruction sucks
|
||||
|
||||
debug(`[got one]n10an`)
|
||||
|
||||
# check enabled
|
||||
`le`
|
||||
`[1=q`
|
||||
debug(`[disabled though]n10an`)
|
||||
`]x`
|
||||
|
||||
# actually quit
|
||||
`le0=!`
|
||||
|
||||
`l1l2*` # calculate the multiply
|
||||
`lo+so` # add it into output
|
||||
|
||||
set_state(search_mul)
|
||||
|
||||
end
|
||||
|
||||
function read_number
|
||||
read_number_start()
|
||||
read_number_end()
|
||||
end
|
||||
|
||||
function read_number_start
|
||||
`_1`
|
||||
# ret _1 if not a digit
|
||||
`ln48>q`
|
||||
`ln57<q`
|
||||
`s.`
|
||||
|
||||
# throw the true digit onto the stack
|
||||
`ln48-`
|
||||
|
||||
# inc i
|
||||
`li1+dsi;Isn`
|
||||
# recurse
|
||||
read_number_start()
|
||||
|
||||
end
|
||||
|
||||
function read_number_end
|
||||
|
||||
# if we only have 1 item on stack (-1) we found no number, so return
|
||||
`z1=q`
|
||||
|
||||
# push entire number thing onto temporary stack
|
||||
`[STz0<.]ds.x`
|
||||
# multiply ten then pop and add repeatedly until done
|
||||
`0`
|
||||
`[LTd_1=qr10*+l.x]ds.x`
|
||||
# get rid of the extra -1
|
||||
`s.`
|
||||
# decrement i so we reread the skipped char
|
||||
`li1-dsi;Isn`
|
||||
|
||||
end
|
||||
128
src/pladcl/2024/day4/part1.pdl
Normal file
128
src/pladcl/2024/day4/part1.pdl
Normal file
@@ -0,0 +1,128 @@
|
||||
state seek_newline
|
||||
|
||||
# if not newline quit
|
||||
`ln10!=q`
|
||||
|
||||
# get the width (plus1 cause newline)
|
||||
`li1+sw`
|
||||
|
||||
# go back to start
|
||||
set_state(findxmas)
|
||||
rewind()
|
||||
|
||||
end
|
||||
|
||||
state findxmas
|
||||
|
||||
`[lo1+so]s.` # increment
|
||||
|
||||
streq(0, "XMAS")
|
||||
`1=.` # inc if equal
|
||||
|
||||
streq(1, "SAMX")
|
||||
`1=.` # inc if equal
|
||||
|
||||
# verts
|
||||
search_down_xmas()
|
||||
search_down_samx()
|
||||
|
||||
search_dr_xmas()
|
||||
search_dr_samx()
|
||||
|
||||
search_dl_xmas()
|
||||
search_dl_samx()
|
||||
|
||||
debug(`lon10an`)
|
||||
|
||||
end
|
||||
|
||||
function search_down_xmas
|
||||
|
||||
#debug_print("hello")
|
||||
#debug(`li;In10an`)
|
||||
|
||||
`li;I88!=q` # if index is not X quit
|
||||
|
||||
#debug_print("1")
|
||||
#debug(`lilw+;In10an`)
|
||||
|
||||
`lilw+;I77!=q` # if index + width is not M quit
|
||||
|
||||
#debug_print("2")
|
||||
#debug(`lilw2*+;In10an`)
|
||||
|
||||
`lilw2*+;I65!=q` # if index + 2* width iw not A quit
|
||||
|
||||
#debug_print("3")
|
||||
|
||||
`lilw3*+;I83!=q` # if index + 3* width is not A quit
|
||||
|
||||
#debug_print("4")
|
||||
|
||||
`lo1+so` # increment
|
||||
|
||||
end
|
||||
|
||||
function search_down_samx
|
||||
|
||||
#debug_print("hello")
|
||||
#debug(`li;In10an`)
|
||||
|
||||
`li;I83!=q`
|
||||
`lilw+;I65!=q`
|
||||
`lilw2*+;I77!=q`
|
||||
`lilw3*+;I88!=q`
|
||||
`lo1+so` # increment
|
||||
|
||||
end
|
||||
|
||||
function search_dr_xmas
|
||||
|
||||
`li;I88!=q`
|
||||
`lilw1++;I77!=q`
|
||||
`lilw1+2*+;I65!=q`
|
||||
`lilw1+3*+;I83!=q`
|
||||
`lo1+so` # increment
|
||||
|
||||
end
|
||||
|
||||
|
||||
function search_dr_samx
|
||||
|
||||
`li;I83!=q`
|
||||
`lilw1++;I65!=q`
|
||||
`lilw1+2*+;I77!=q`
|
||||
`lilw1+3*+;I88!=q`
|
||||
`lo1+so` # increment
|
||||
|
||||
end
|
||||
|
||||
function search_dl_xmas
|
||||
|
||||
`li;I88!=q`
|
||||
`lilw1-+;I77!=q`
|
||||
`lilw1-2*+;I65!=q`
|
||||
`lilw1-3*+;I83!=q`
|
||||
`lo1+so` # increment
|
||||
|
||||
end
|
||||
|
||||
|
||||
function search_dl_samx
|
||||
|
||||
`li;I83!=q`
|
||||
`lilw1-+;I65!=q`
|
||||
`lilw1-2*+;I77!=q`
|
||||
`lilw1-3*+;I88!=q`
|
||||
`lo1+so` # increment
|
||||
|
||||
end
|
||||
|
||||
interrupt program_start
|
||||
`0so` # start output as 0
|
||||
end
|
||||
|
||||
interrupt program_end
|
||||
debug(`lwn10an`)
|
||||
`lon`
|
||||
end
|
||||
85
src/pladcl/2024/day4/part2.pdl
Normal file
85
src/pladcl/2024/day4/part2.pdl
Normal file
@@ -0,0 +1,85 @@
|
||||
state seek_newline
|
||||
|
||||
# if not newline quit
|
||||
`ln10!=q`
|
||||
|
||||
# get the width (plus1 cause newline)
|
||||
`li1+sw`
|
||||
|
||||
# go back to start
|
||||
set_state(findxmas)
|
||||
rewind()
|
||||
|
||||
end
|
||||
|
||||
state findxmas
|
||||
|
||||
search_mm()
|
||||
search_sm()
|
||||
search_ms()
|
||||
search_ss()
|
||||
|
||||
debug(`lon10an`)
|
||||
|
||||
end
|
||||
|
||||
function search_mm
|
||||
|
||||
# x y
|
||||
`li;I77!=q` # [0][0] = m
|
||||
`li2+;I77!=q` # [0][2] = m
|
||||
`lilw1++;I65!=q` # [1][1] = a
|
||||
`lilw2*+;I83!=q` # [2][0] = s
|
||||
`lilw1+2*+;I83!=q` # [2][2] = s
|
||||
|
||||
`lo1+so` # increment
|
||||
|
||||
end
|
||||
|
||||
function search_sm
|
||||
|
||||
# x y
|
||||
`li;I83!=q` # [0][0] = s
|
||||
`li2+;I77!=q` # [0][2] = m
|
||||
`lilw1++;I65!=q` # [1][1] = a
|
||||
`lilw2*+;I83!=q` # [2][0] = s
|
||||
`lilw1+2*+;I77!=q` # [2][2] = m
|
||||
|
||||
`lo1+so` # increment
|
||||
|
||||
end
|
||||
|
||||
function search_ms
|
||||
|
||||
# x y
|
||||
`li;I77!=q` # [0][0] = m
|
||||
`li2+;I83!=q` # [0][2] = s
|
||||
`lilw1++;I65!=q` # [1][1] = a
|
||||
`lilw2*+;I77!=q` # [2][0] = m
|
||||
`lilw1+2*+;I83!=q` # [2][2] = s
|
||||
|
||||
`lo1+so` # increment
|
||||
|
||||
end
|
||||
|
||||
function search_ss
|
||||
|
||||
# x y
|
||||
`li;I83!=q` # [0][0] = m
|
||||
`li2+;I83!=q` # [0][2] = m
|
||||
`lilw1++;I65!=q` # [1][1] = a
|
||||
`lilw2*+;I77!=q` # [2][0] = s
|
||||
`lilw1+2*+;I77!=q` # [2][2] = s
|
||||
|
||||
`lo1+so` # increment
|
||||
|
||||
end
|
||||
|
||||
interrupt program_start
|
||||
`0so` # start output as 0
|
||||
end
|
||||
|
||||
interrupt program_end
|
||||
debug(`lwn10an`)
|
||||
`lon`
|
||||
end
|
||||
172
src/pladcl/2024/day5/part1.pdl
Normal file
172
src/pladcl/2024/day5/part1.pdl
Normal file
@@ -0,0 +1,172 @@
|
||||
state rule_read_first
|
||||
read_number()
|
||||
`s1` # store this in 1
|
||||
set_state(rule_read_second)
|
||||
end
|
||||
|
||||
state rule_read_second
|
||||
return_if(`ln` == 124)
|
||||
read_number()
|
||||
|
||||
# calculate list size
|
||||
`l1;$`
|
||||
|
||||
# calculate list offset
|
||||
`l1`
|
||||
`100*+` # num * 100 + size
|
||||
|
||||
`:%` # store the num on the array
|
||||
|
||||
`l1;$1+` # inc size
|
||||
`l1:$` # and store
|
||||
|
||||
end
|
||||
|
||||
state manual_read
|
||||
|
||||
return_if(`ln` == 44)
|
||||
read_number()
|
||||
`lc:3` # store it in an array at C
|
||||
`lc1+sc`
|
||||
|
||||
end
|
||||
|
||||
interrupt newline
|
||||
|
||||
if `l=` == 2 then
|
||||
|
||||
if verify_manual() == 1 then
|
||||
get_middle()
|
||||
`lo+so`
|
||||
end
|
||||
|
||||
adjust_index(1)
|
||||
|
||||
`0sc`
|
||||
end
|
||||
|
||||
|
||||
# rule reading
|
||||
if `l=` == 1 then
|
||||
|
||||
adjust_index(1) # increment to next
|
||||
set_state(rule_read_first)
|
||||
|
||||
# if still newline
|
||||
if `ln` == 10 then
|
||||
set_state(manual_read)
|
||||
`0sc`
|
||||
`2s=`
|
||||
adjust_index(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function get_middle
|
||||
|
||||
`lc2/` # get middle
|
||||
`;3` # and index
|
||||
|
||||
end
|
||||
|
||||
# ok.
|
||||
function verify_manual
|
||||
|
||||
# from 0 to c - 1
|
||||
`0s!`
|
||||
while `l!` < `lc1-` do
|
||||
|
||||
# load list offset
|
||||
`l!;3`
|
||||
`100*s1`
|
||||
|
||||
# from ! + 1 to c
|
||||
`l!1+s?`
|
||||
while `l?` < `lc` do
|
||||
`l?;3`
|
||||
`s2` # load value
|
||||
|
||||
# return 0 if not found
|
||||
if list_lookup() == 0 then
|
||||
return 0
|
||||
end
|
||||
`l?1+s?`
|
||||
end
|
||||
`l!1+s!`
|
||||
end
|
||||
|
||||
1
|
||||
|
||||
end
|
||||
|
||||
|
||||
# takes offset in 1, value in 2
|
||||
function list_lookup
|
||||
|
||||
# so we don't clobber 1
|
||||
`l1s.`
|
||||
|
||||
while `l.;%` != 0 do
|
||||
if `l.;%` == `l2` then
|
||||
return 1
|
||||
end
|
||||
`l.1+s.`
|
||||
end
|
||||
|
||||
0
|
||||
end
|
||||
|
||||
|
||||
|
||||
interrupt program_start
|
||||
`1s=`
|
||||
end
|
||||
|
||||
interrupt program_end
|
||||
`lop`
|
||||
end
|
||||
|
||||
function read_number
|
||||
read_number_start()
|
||||
read_number_end()
|
||||
end
|
||||
|
||||
function read_number_start
|
||||
|
||||
-1
|
||||
# ret _1 if not a digit
|
||||
return_if(`ln` < 48)
|
||||
return_if(`ln` > 57)
|
||||
`st`
|
||||
|
||||
# throw the true digit onto the stack
|
||||
`ln48-`
|
||||
|
||||
# inc i
|
||||
adjust_index(1)
|
||||
# recurse
|
||||
read_number_start()
|
||||
|
||||
end
|
||||
|
||||
function read_number_end
|
||||
|
||||
# if we only have 1 item on stack (-1) we found no number, so return
|
||||
return_if(1 == `z`)
|
||||
|
||||
# push entire number thing onto temporary stack
|
||||
`[STz0<.]ds.x`
|
||||
# multiply ten then pop and add repeatedly until done
|
||||
`0`
|
||||
`[LTd_1=qr10*+l.x]ds.x`
|
||||
# get rid of the extra -1
|
||||
`st`
|
||||
# decrement i so we reread the skipped char
|
||||
adjust_index(-1)
|
||||
|
||||
end
|
||||
|
||||
function abs
|
||||
`d0<q0r-`
|
||||
end
|
||||
205
src/pladcl/2024/day5/part2.pdl
Normal file
205
src/pladcl/2024/day5/part2.pdl
Normal file
@@ -0,0 +1,205 @@
|
||||
state rule_read_first
|
||||
read_number()
|
||||
`s1` # store this in 1
|
||||
set_state(rule_read_second)
|
||||
end
|
||||
|
||||
state rule_read_second
|
||||
return_if(`ln` == 124)
|
||||
read_number()
|
||||
|
||||
# calculate list size
|
||||
`l1;$`
|
||||
|
||||
# calculate list offset
|
||||
`l1`
|
||||
`100*+` # num * 100 + size
|
||||
|
||||
`:%` # store the num on the array
|
||||
|
||||
`l1;$1+` # inc size
|
||||
`l1:$` # and store
|
||||
|
||||
end
|
||||
|
||||
state manual_read
|
||||
|
||||
return_if(`ln` == 44)
|
||||
read_number()
|
||||
`lc:3` # store it in an array at C
|
||||
`lc1+sc`
|
||||
|
||||
end
|
||||
|
||||
interrupt newline
|
||||
|
||||
if `l=` == 2 then
|
||||
|
||||
if verify_manual() == 0 then
|
||||
debug(`[wowie]n10an`)
|
||||
fix_manual()
|
||||
get_middle()
|
||||
`lo+so`
|
||||
end
|
||||
|
||||
adjust_index(1)
|
||||
|
||||
`0sc`
|
||||
end
|
||||
|
||||
|
||||
# rule reading
|
||||
if `l=` == 1 then
|
||||
|
||||
adjust_index(1) # increment to next
|
||||
set_state(rule_read_first)
|
||||
|
||||
# if still newline
|
||||
if `ln` == 10 then
|
||||
set_state(manual_read)
|
||||
`0sc`
|
||||
`2s=`
|
||||
adjust_index(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function fix_manual
|
||||
|
||||
# from 0 to c
|
||||
`0s!`
|
||||
while `l!` < `lc` do
|
||||
|
||||
# load list offset
|
||||
`l!;3`
|
||||
`100*s1`
|
||||
|
||||
# from 0 to c
|
||||
`0s?`
|
||||
`0` # start sum
|
||||
while `l?` < `lc` do
|
||||
if `l?` != `l!` then
|
||||
# load value
|
||||
`l?;3s2`
|
||||
list_lookup()
|
||||
`+` # add lookup into sum
|
||||
|
||||
end
|
||||
`l?1+s?`
|
||||
end
|
||||
|
||||
`lcr-1-` # reverse index
|
||||
`l!;3` # load number
|
||||
`r:4` # store into 4
|
||||
`l!1+s!`
|
||||
end
|
||||
end
|
||||
|
||||
function get_middle
|
||||
|
||||
`lc2/` # get middle
|
||||
`;4` # and index
|
||||
|
||||
end
|
||||
|
||||
# ok.
|
||||
function verify_manual
|
||||
|
||||
# from 0 to c - 1
|
||||
`0s!`
|
||||
while `l!` < `lc1-` do
|
||||
|
||||
# load list offset
|
||||
`l!;3`
|
||||
`100*s1`
|
||||
|
||||
# from ! + 1 to c
|
||||
`l!1+s?`
|
||||
while `l?` < `lc` do
|
||||
`l?;3`
|
||||
`s2` # load value
|
||||
|
||||
# return 0 if not found
|
||||
if list_lookup() == 0 then
|
||||
return 0
|
||||
end
|
||||
`l?1+s?`
|
||||
end
|
||||
`l!1+s!`
|
||||
end
|
||||
|
||||
1
|
||||
|
||||
end
|
||||
|
||||
|
||||
# takes offset in 1, value in 2
|
||||
function list_lookup
|
||||
|
||||
# so we don't clobber 1
|
||||
`l1s.`
|
||||
|
||||
while `l.;%` != 0 do
|
||||
if `l.;%` == `l2` then
|
||||
return 1
|
||||
end
|
||||
`l.1+s.`
|
||||
end
|
||||
|
||||
0
|
||||
end
|
||||
|
||||
|
||||
|
||||
interrupt program_start
|
||||
`1s=`
|
||||
end
|
||||
|
||||
interrupt program_end
|
||||
`lop`
|
||||
end
|
||||
|
||||
function read_number
|
||||
read_number_start()
|
||||
read_number_end()
|
||||
end
|
||||
|
||||
function read_number_start
|
||||
|
||||
-1
|
||||
# ret _1 if not a digit
|
||||
return_if(`ln` < 48)
|
||||
return_if(`ln` > 57)
|
||||
`st`
|
||||
|
||||
# throw the true digit onto the stack
|
||||
`ln48-`
|
||||
|
||||
# inc i
|
||||
adjust_index(1)
|
||||
# recurse
|
||||
read_number_start()
|
||||
|
||||
end
|
||||
|
||||
function read_number_end
|
||||
|
||||
# if we only have 1 item on stack (-1) we found no number, so return
|
||||
return_if(1 == `z`)
|
||||
|
||||
# push entire number thing onto temporary stack
|
||||
`[STz0<.]ds.x`
|
||||
# multiply ten then pop and add repeatedly until done
|
||||
`0`
|
||||
`[LTd_1=qr10*+l.x]ds.x`
|
||||
# get rid of the extra -1
|
||||
`st`
|
||||
# decrement i so we reread the skipped char
|
||||
adjust_index(-1)
|
||||
|
||||
end
|
||||
|
||||
function abs
|
||||
`d0<q0r-`
|
||||
end
|
||||
5
src/python/2023/day1/part1.py
Normal file
5
src/python/2023/day1/part1.py
Normal file
@@ -0,0 +1,5 @@
|
||||
print(
|
||||
sum([a[0]*10 + a[-1] for a in [[int(b) for b in c if b.isnumeric()] for c in open('resources/2023/day1.txt').read().split("\n")[:-1]]])
|
||||
)
|
||||
|
||||
# sum([a[0]*10 + a[-1] for a in [[int(b) for b in c if b.isnumeric()] for c in open('resources/2023/day1.txt').read().split("\n")[:-1]]])
|
||||
14
src/python/2023/day1/part2.py
Normal file
14
src/python/2023/day1/part2.py
Normal file
@@ -0,0 +1,14 @@
|
||||
|
||||
print(
|
||||
sum(
|
||||
[a[0]*10 + a[-1] for a in
|
||||
[
|
||||
[int(b) for b in c.replace("eight", "e8t").replace("two", "2o").replace("one", "1").replace("five", "5").replace("seven", "7n")
|
||||
.replace("nine", "9").replace("six", '6').replace("four", "4").replace("three", "3") if b.isnumeric()
|
||||
] for c in open('resources/2023/day1.txt').read().split("\n")[:-1]
|
||||
]
|
||||
]
|
||||
)
|
||||
)
|
||||
|
||||
# sum([a[0]*10 + a[-1] for a in [[int(b) for b in c.replace("eight", "e8t").replace("two", "2o").replace("one", "1").replace("five", "5").replace("seven", "7n").replace("nine", "9").replace("six", '6').replace("four", "4").replace("three", "3") if b.isnumeric()] for c in open('resources/2023/day1.txt').read().split("\n")[:-1]]])
|
||||
14
src/python/2023/day2/part1.py
Normal file
14
src/python/2023/day2/part1.py
Normal file
@@ -0,0 +1,14 @@
|
||||
|
||||
print(
|
||||
sum([
|
||||
(y+1) * (0 if
|
||||
(
|
||||
sum([int(x.split(" ")[0]) > 12 for x in z.split(": ")[1][:-1].replace(";", ",").split(", ") if 'red' in x]) +
|
||||
sum([int(x.split(" ")[0]) > 13 for x in z.split(": ")[1][:-1].replace(";", ",").split(", ") if 'green' in x]) +
|
||||
sum([int(x.split(" ")[0]) > 14 for x in z.split(": ")[1][:-1].replace(";", ",").split(", ") if 'blue' in x])
|
||||
) > 0 else 1)
|
||||
for y, z in enumerate(open('resources/2023/day2.txt').readlines())
|
||||
])
|
||||
)
|
||||
|
||||
# sum([(y+1) * (0 if (sum([int(x.split(" ")[0]) > 12 for x in z.split(": ")[1][:-1].replace(";", ",").split(", ") if 'red' in x]) + sum([int(x.split(" ")[0]) > 13 for x in z.split(": ")[1][:-1].replace(";", ",").split(", ") if 'green' in x]) + sum([int(x.split(" ")[0]) > 14 for x in z.split(": ")[1][:-1].replace(";", ",").split(", ") if 'blue' in x])) > 0 else 1) for y, z in enumerate(open('resources/2023/day2.txt').readlines())])
|
||||
12
src/python/2023/day2/part2.py
Normal file
12
src/python/2023/day2/part2.py
Normal file
@@ -0,0 +1,12 @@
|
||||
print(
|
||||
sum(
|
||||
[
|
||||
max([int(x.split(" ")[0]) for x in z.split(": ")[1][:-1].replace(";", ",").split(", ") if 'red' in x]) *
|
||||
max([int(x.split(" ")[0]) for x in z.split(": ")[1][:-1].replace(";", ",").split(", ") if 'green' in x]) *
|
||||
max([int(x.split(" ")[0]) for x in z.split(": ")[1][:-1].replace(";", ",").split(", ") if 'blue' in x])
|
||||
for z in open('resources/2023/day2.txt').readlines()
|
||||
]
|
||||
)
|
||||
)
|
||||
|
||||
# sum([max([int(x.split(" ")[0]) for x in z.split(": ")[1][:-1].replace(";", ",").split(", ") if 'red' in x]) * max([int(x.split(" ")[0]) for x in z.split(": ")[1][:-1].replace(";", ",").split(", ") if 'green' in x]) * max([int(x.split(" ")[0]) for x in z.split(": ")[1][:-1].replace(";", ",").split(", ") if 'blue' in x]) for z in open('resources/2023/day2.txt').readlines()])
|
||||
21
src/python/2023/day3/part1.py
Normal file
21
src/python/2023/day3/part1.py
Normal file
@@ -0,0 +1,21 @@
|
||||
print(sum(sum(
|
||||
[[m[2] for m in zip(*l) if m[0] and not (m[1] and m[2] == m[3]) and m[2] != -1] for l in
|
||||
list(map(lambda x, y: (x, [False] + x, y, [-1] + y),
|
||||
[[sum(n) > 0 for n in zip(*m)] for m in zip(
|
||||
*list(map(lambda x: [
|
||||
[[False] + q for q in [[False] * len(x[0])] + x], [[False] * len(x[0])] + x, [q[1:] + [False] for q in [[False] * len(x[0])] + x],
|
||||
[[False] + q for q in x], x, [q[1:] + [False] for q in x],
|
||||
[[False] + q for q in x[1:] + [[False] * len(x[0])]], x[1:] + [[False] * len(x[0])], [q[1:] + [False] for q in x[1:] + [[False] * len(x[0])]]],
|
||||
[[[x not in '0123456789.' for x in l] for l in open("resources/2023/day3.txt").read().split("\n")]] # array of True when a symbol
|
||||
))[0]
|
||||
)], # array of True when next to a symbol
|
||||
[[max(a) if a[1] != -1 else -1 for a in zip(*b)] for b in zip(
|
||||
*list(map(lambda x: [[[-1] + q for q in x], x, [q[1:] + [-1] for q in x]],
|
||||
[[[int("".join(c).strip('.!@#$%^&*()_+-=/')) if c[1] in '0123456789' else -1 for c in zip('.' + l, l, l[1:] + '.')] for l in open("resources/2023/day3.txt").read().split("\n")]]
|
||||
))[0]
|
||||
)] # array of -1, or the number.
|
||||
))
|
||||
], []
|
||||
)))
|
||||
|
||||
# sum(sum([[m[2] for m in zip(*l) if m[0] and not (m[1] and m[2] == m[3]) and m[2] != -1] for l in list(map(lambda x, y: (x, [False] + x, y, [-1] + y), [[sum(n) > 0 for n in zip(*m)] for m in zip(*list(map(lambda x: [[[False] + q for q in [[False] * len(x[0])] + x], [[False] * len(x[0])] + x, [q[1:] + [False] for q in [[False] * len(x[0])] + x], [[False] + q for q in x], x, [q[1:] + [False] for q in x], [[False] + q for q in x[1:] + [[False] * len(x[0])]], x[1:] + [[False] * len(x[0])], [q[1:] + [False] for q in x[1:] + [[False] * len(x[0])]]], [[[x not in '0123456789.' for x in l] for l in open("resources/2023/day3.txt").read().split("\n")]]))[0])], [[max(a) if a[1] != -1 else -1 for a in zip(*b)] for b in zip(*list(map(lambda x: [[[-1] + q for q in x], x, [q[1:] + [-1] for q in x]], [[[int("".join(c).strip('.!@#$%^&*()_+-=/')) if c[1] in '0123456789' else -1 for c in zip('.' + l, l, l[1:] + '.')] for l in open("resources/2023/day3.txt").read().split("\n")]]))[0])]))], []))
|
||||
28
src/python/2023/day3/part2.py
Normal file
28
src/python/2023/day3/part2.py
Normal file
@@ -0,0 +1,28 @@
|
||||
print(sum([
|
||||
v[0] * v[1] for v in # sums all asterisks with > 2
|
||||
[
|
||||
[sum([g[w, a] for a in range(140) if abs(w - a*140) < 280], []) for w in range(140**2)] for g in # coagulate the dictionaries
|
||||
[{
|
||||
(r*140 + p, r): [m[2] for m in zip(*l) if m[0] and not (m[1] and m[2] == m[3]) and m[2] != -1 and r*140 + p in m[0]] # find adjacent numbers
|
||||
for p in range(-280, 280) for r, l in enumerate( # from part 1.
|
||||
list(map(lambda x, y: (x, [-1] + x, y, [-1] + y),
|
||||
[[[l for l in n if l > 0] for n in zip(*m)] for m in zip(
|
||||
*list(map(lambda x: [
|
||||
[[False] + q for q in [[False] * len(x[0])] + x], [[False] * len(x[0])] + x, [q[1:] + [False] for q in [[False] * len(x[0])] + x],
|
||||
[[False] + q for q in x], x, [q[1:] + [False] for q in x],
|
||||
[[False] + q for q in x[1:] + [[False] * len(x[0])]], x[1:] + [[False] * len(x[0])], [q[1:] + [False] for q in x[1:] + [[False] * len(x[0])]]],
|
||||
[[[i * 140 + j if b == "*" else -1 for j, b in enumerate(a)] for i, a in enumerate(open("resources/2023/day3.txt").read().split("\n"))]] # array of asterisk ids, or -1
|
||||
))[0]
|
||||
)], # array of nearby asterissks + id
|
||||
[[max(a) if a[1] != -1 else -1 for a in zip(*b)] for b in zip(
|
||||
*list(map(lambda x: [[[-1] + q for q in x], x, [q[1:] + [-1] for q in x]],
|
||||
[[[int("".join(c).strip('.!@#$%^&*()_+-=/')) if c[1] in '0123456789' else -1 for c in zip('.' + l, l, l[1:] + '.')] for l in open("resources/2023/day3.txt").read().split("\n")]]
|
||||
))[0]
|
||||
)] # array of -1, or the number.
|
||||
))
|
||||
)
|
||||
}]
|
||||
][0] if len(v) >= 2
|
||||
]))
|
||||
|
||||
# sum([v[0] * v[1] for v in [[sum([g[w, a] for a in range(140) if abs(w - a*140) < 280], []) for w in range(140**2)] for g in [{(r*140 + p, r): [m[2] for m in zip(*l) if m[0] and not (m[1] and m[2] == m[3]) and m[2] != -1 and r*140 + p in m[0]] for p in range(-280, 280) for r, l in enumerate(list(map(lambda x, y: (x, [-1] + x, y, [-1] + y), [[[l for l in n if l > 0] for n in zip(*m)] for m in zip(*list(map(lambda x: [[[False] + q for q in [[False] * len(x[0])] + x], [[False] * len(x[0])] + x, [q[1:] + [False] for q in [[False] * len(x[0])] + x],[[False] + q for q in x], x, [q[1:] + [False] for q in x], [[False] + q for q in x[1:] + [[False] * len(x[0])]], x[1:] + [[False] * len(x[0])], [q[1:] + [False] for q in x[1:] + [[False] * len(x[0])]]], [[[i * 140 + j if b == "*" else -1 for j, b in enumerate(a)] for i, a in enumerate(open("resources/2023/day3.txt").read().split("\n"))]]))[0])], [[max(a) if a[1] != -1 else -1 for a in zip(*b)] for b in zip(*list(map(lambda x: [[[-1] + q for q in x], x, [q[1:] + [-1] for q in x]], [[[int("".join(c).strip('.!@#$%^&*()_+-=/')) if c[1] in '0123456789' else -1 for c in zip('.' + l, l, l[1:] + '.')] for l in open("resources/2023/day3.txt").read().split("\n")]]))[0])])))}]][0] if len(v) >= 2])
|
||||
11
src/python/2023/day4/part1.py
Normal file
11
src/python/2023/day4/part1.py
Normal file
@@ -0,0 +1,11 @@
|
||||
print(
|
||||
sum([[0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512][p] for p in
|
||||
[sum(
|
||||
[[b in x[0] for b in x[1]] for x in [
|
||||
[[int(y) for y in x.strip().split(" ") if len(y) != 0] for x in l.split(':')[1].split("|")]
|
||||
]][0]
|
||||
) for l in open("resources/2023/day4.txt").readlines()]
|
||||
])
|
||||
)
|
||||
|
||||
# sum([[0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512][p] for p in [sum([[b in x[0] for b in x[1]] for x in [[[int(y) for y in x.strip().split(" ") if len(y) != 0] for x in l.split(':')[1].split("|")]]][0]) for l in open("resources/2023/day4.txt").readlines()]])
|
||||
34
src/python/2023/day4/part2.py
Normal file
34
src/python/2023/day4/part2.py
Normal file
@@ -0,0 +1,34 @@
|
||||
def print2d(x):
|
||||
print("\n".join([str(xx) for xx in x]))
|
||||
|
||||
a = [sum(
|
||||
[[b in x[0] for b in x[1]] for x in [
|
||||
[[int(y) for y in x.strip().split(" ") if len(y) != 0] for x in l.split(':')[1].split("|")]
|
||||
]][0]
|
||||
) for l in open("resources/2023/day4.txt").readlines()]
|
||||
|
||||
# print(a)
|
||||
|
||||
b = [
|
||||
[d[x] for x in range(20) for d in [a]]
|
||||
]
|
||||
|
||||
|
||||
e = [2, 1, 1, 0, 0]
|
||||
|
||||
# [1, 2, 4, 5, 1]
|
||||
|
||||
# [0, 1, 1, 0, 0]
|
||||
# [0, 0, 1, 0, 0]
|
||||
# [0, 0, 0, 1, 0]
|
||||
# [0, 0, 0, 0, 0]
|
||||
# [0, 0, 0, 0, 0]
|
||||
|
||||
p = [[1 if x > c and x < c + 1 + i else 0 for x in range(5)] for c, i in enumerate(e)]
|
||||
|
||||
print2d(p)
|
||||
print(p)
|
||||
|
||||
print([
|
||||
[sum([p[x][y] for x in range(5)]) for y in range(5)]
|
||||
])
|
||||
53
src/python/2023/day5/part1.py
Normal file
53
src/python/2023/day5/part1.py
Normal file
@@ -0,0 +1,53 @@
|
||||
print(
|
||||
min(
|
||||
[
|
||||
[
|
||||
[
|
||||
max(f) if max(f) != -1 else h
|
||||
for f in [[g(h) for g in m[6]]] # final map
|
||||
][0] for h in [
|
||||
[
|
||||
max(f) if max(f) != -1 else h
|
||||
for f in [[g(h) for g in m[5]]] # sixth map
|
||||
][0] for h in [
|
||||
[
|
||||
max(f) if max(f) != -1 else h
|
||||
for f in [[g(h) for g in m[4]]] # fifth map
|
||||
][0] for h in [
|
||||
[
|
||||
max(f) if max(f) != -1 else h
|
||||
for f in [[g(h) for g in m[3]]] # fourth map
|
||||
][0] for h in [
|
||||
[
|
||||
max(f) if max(f) != -1 else h
|
||||
for f in [[g(h) for g in m[2]]] # third map
|
||||
][0] for h in [
|
||||
[
|
||||
max(f) if max(f) != -1 else h
|
||||
for f in [[g(h) for g in m[1]]] # second map
|
||||
][0] for h in [
|
||||
[
|
||||
max(f) if max(f) != -1 else h
|
||||
for f in [[g(h) for g in m[0]]] # first map
|
||||
][0] for h in [
|
||||
int(x) for x in open("resources/2023/day5.txt").readlines()[0].split(":")[1].strip().split(" ") # seeds
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
] for m in [[
|
||||
list(map(
|
||||
lambda d: lambda e: e + d[0] - d[1] if e >= d[1] and e < d[1] + d[2] else -1,
|
||||
[[int(a) for a in b.split(" ")] for b in c.strip().split("\n")[1:]] # bullshit to get maps
|
||||
))
|
||||
for c in open("resources/2023/day5.txt").read().split("\n\n")[1:] # maps
|
||||
]]
|
||||
][0]
|
||||
)
|
||||
)
|
||||
|
||||
#min([[[max(f) if max(f) != -1 else h for f in [[g(h) for g in m[6]]]][0] for h in [[max(f) if max(f) != -1 else h for f in [[g(h) for g in m[5]]]][0] for h in [[max(f) if max(f) != -1 else h for f in [[g(h) for g in m[4]]]][0] for h in [[max(f) if max(f) != -1 else h for f in [[g(h) for g in m[3]]]][0] for h in [[max(f) if max(f) != -1 else h for f in [[g(h) for g in m[2]]]][0] for h in [[max(f) if max(f) != -1 else h for f in [[g(h) for g in m[1]]]][0] for h in [[max(f) if max(f) != -1 else h for f in [[g(h) for g in m[0]]]][0] for h in [int(x) for x in open("resources/2023/day5.txt").readlines()[0].split(":")[1].strip().split(" ")]]]]]]]] for m in [[list(map(lambda d: lambda e: e + d[0] - d[1] if e >= d[1] and e < d[1] + d[2] else -1, [[int(a) for a in b.split(" ")] for b in c.strip().split("\n")[1:]])) for c in open("resources/2023/day5.txt").read().split("\n\n")[1:]]]][0])
|
||||
|
||||
19
src/python/2023/day7/part1.py
Normal file
19
src/python/2023/day7/part1.py
Normal file
@@ -0,0 +1,19 @@
|
||||
print(
|
||||
sum([a * (c + 1) for c, (_, a) in enumerate(sorted( # sort by hand value and payout bets according to rank
|
||||
[(sum([ # total hand value
|
||||
[max(
|
||||
13**5 * 6 if 5 in d else 0, # five of a kind
|
||||
13**5 * 5 if 4 in d else 0, # four of a kind
|
||||
13**5 * 4 if 3 in d and 2 in d else 0, # full house
|
||||
13**5 * 3 if 3 in d else 0, # three of a kind
|
||||
13**5 * 2 if list(d).count(2) == 2 else 0, # two pair
|
||||
13**5 if 2 in d else 0 # pair
|
||||
) for d in [{k: b.count(k) for k in b}.values()]][0], # total type value (value from the type of hand)
|
||||
sum([13**(4 - e) * '23456789TJQKA'.index(a) for e, a in enumerate(b)]) # total card value (value from the type of card)
|
||||
]), int(v)) # makes an array of form (total hand value, bet)
|
||||
for b, v in [x.split(' ') for x in open('resources/2023/day7.txt').read().split("\n")] # reads file split on \n
|
||||
]
|
||||
))])
|
||||
)
|
||||
|
||||
#sum([a * (c + 1) for c, (_, a) in enumerate(sorted([(sum([[max(13**5 * 6 if 5 in d else 0, 13**5 * 5 if 4 in d else 0, 13**5 * 4 if 3 in d and 2 in d else 0, 13**5 * 3 if 3 in d else 0, 13**5 * 2 if list(d).count(2) == 2 else 0, 13**5 if 2 in d else 0) for d in [{k: b.count(k) for k in b}.values()]][0], sum([13**(4 - e) * '23456789TJQKA'.index(a) for e, a in enumerate(b)])]), int(v)) for b, v in [x.split(' ') for x in open('resources/2023/day7.txt').read().split("\n")]]))])
|
||||
1350
src/z80/2023/day13/input.txt
Normal file
1350
src/z80/2023/day13/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
342
src/z80/2023/day13/part1.z80
Normal file
342
src/z80/2023/day13/part1.z80
Normal file
@@ -0,0 +1,342 @@
|
||||
.org 0x0000
|
||||
|
||||
LD HL, FILE;
|
||||
|
||||
main_loop:
|
||||
|
||||
CALL LOAD_MAP
|
||||
PUSH HL
|
||||
CALL CHECK_MAP
|
||||
POP HL
|
||||
JR C, vert
|
||||
|
||||
;; ld a into bc
|
||||
LD B, 0;
|
||||
LD C, A;
|
||||
|
||||
;; add it into IX
|
||||
ADD IX, BC
|
||||
|
||||
JR vh_end
|
||||
|
||||
vert
|
||||
|
||||
;; ld a into bc
|
||||
LD B, 0;
|
||||
LD C, A;
|
||||
|
||||
;; add it into IY
|
||||
ADD IY, BC
|
||||
|
||||
vh_end
|
||||
|
||||
;; test if (HL) is 0
|
||||
XOR A
|
||||
CP (HL)
|
||||
|
||||
JR NZ, main_loop
|
||||
|
||||
|
||||
;; mult IY by 100 into hl
|
||||
PUSH IY
|
||||
POP HL
|
||||
|
||||
ADD HL, HL
|
||||
ADD HL, HL
|
||||
PUSH HL ; 4
|
||||
ADD HL, HL
|
||||
ADD HL, HL
|
||||
ADD HL, HL
|
||||
PUSH HL ; 32
|
||||
ADD HL, HL ; 64
|
||||
POP BC
|
||||
ADD HL, BC ; 64 + 32
|
||||
POP BC
|
||||
ADD HL, BC ; 64 + 32 + 4
|
||||
|
||||
;; add in IX
|
||||
PUSH IX
|
||||
POP BC
|
||||
ADD HL, BC
|
||||
|
||||
HALT
|
||||
|
||||
; cool funny function stuff
|
||||
|
||||
.org 0x1000
|
||||
|
||||
start
|
||||
defb 00h
|
||||
end
|
||||
defb 00h
|
||||
count
|
||||
defb 00h
|
||||
|
||||
CHECK_V_MIRROR:
|
||||
; map in (HL)
|
||||
; col in A
|
||||
; width in B
|
||||
; height in C
|
||||
|
||||
LD HL, map
|
||||
LD DE, map
|
||||
|
||||
; A = 2 * col - map.width
|
||||
SLA A ; A = 2 * col
|
||||
PUSH AF ; save 2 * col
|
||||
SUB B ; A = 2 * col - map.width
|
||||
|
||||
ADD A, 2 ; for off by 1 errors or some shit idfk
|
||||
|
||||
; clip it to be 0
|
||||
JP P, v_pos
|
||||
LD A, 0
|
||||
v_pos
|
||||
|
||||
LD HL, map
|
||||
|
||||
LD (start), A ; move 2 * col - map width (start check) into start
|
||||
LD L, A ; and to L for safekeeping
|
||||
|
||||
POP AF ; restore A to 2 * col;
|
||||
SUB L ; A = 2 * col - start
|
||||
INC A ; A = 2 * col - start + 1
|
||||
|
||||
LD (end), A ; store that in end
|
||||
|
||||
SUB L ; A is the difference
|
||||
SRL A ; divide by 2
|
||||
INC A ; + 1
|
||||
|
||||
LD (count), A ; you got the counter for the inner loop
|
||||
v_loop_out
|
||||
|
||||
; move col into B for the counter
|
||||
LD A, (count)
|
||||
LD B, A
|
||||
|
||||
; mov start and end into the registers
|
||||
LD A, (start)
|
||||
LD L, A
|
||||
LD A, (end)
|
||||
LD E, A
|
||||
v_loop_in
|
||||
|
||||
; compare the two characters
|
||||
LD A, (DE)
|
||||
CP A, (HL)
|
||||
|
||||
; return NZ if they're not equal
|
||||
RET NZ
|
||||
|
||||
; next character
|
||||
DEC E
|
||||
INC L
|
||||
|
||||
; :clap: :clap: next meme
|
||||
DEC B
|
||||
JR NZ, v_loop_in
|
||||
vq
|
||||
|
||||
;; go to next line
|
||||
INC H
|
||||
INC D
|
||||
|
||||
DEC C ; dec the loop counter and loop if negative
|
||||
JP NZ, v_loop_out
|
||||
vq2
|
||||
|
||||
XOR A ; set zero flag and return
|
||||
RET
|
||||
|
||||
CHECK_H_MIRROR:
|
||||
; map in (HL)
|
||||
; col in A
|
||||
; width in B
|
||||
; height in C
|
||||
|
||||
LD HL, map
|
||||
LD DE, map
|
||||
|
||||
; A = 2 * col - map.height
|
||||
SLA A ; A = 2 * col
|
||||
PUSH AF ; save 2 * col
|
||||
SUB C ; A = 2 * col - map.height
|
||||
|
||||
ADD A, 2 ; for off by 1 errors or some shit idfk
|
||||
|
||||
; clip it to be 0
|
||||
JP P, h_pos
|
||||
LD A, 0
|
||||
h_pos
|
||||
|
||||
LD (start), A ; move 2 * col - map width (start check) into start
|
||||
LD D, A ; and to L for safekeeping
|
||||
|
||||
POP AF ; restore A to 2 * col;
|
||||
SUB D ; A = 2 * col - start
|
||||
INC A ; A = 2 * col - start + 1
|
||||
|
||||
LD (end), A ; store that in end
|
||||
|
||||
SUB D ; A is the difference
|
||||
SRL A ; divide by 2
|
||||
INC A ; + 1
|
||||
|
||||
LD (count), A ; you got the counter for the inner loop
|
||||
h_loop_out
|
||||
|
||||
; move col into C for the counter
|
||||
LD A, (count)
|
||||
LD C, A
|
||||
|
||||
; mov start and end into the registers
|
||||
LD A, (start)
|
||||
ADD A, 60h
|
||||
LD H, A
|
||||
LD A, (end)
|
||||
ADD A, 60h
|
||||
LD D, A
|
||||
h_loop_in
|
||||
|
||||
; compare the two characters
|
||||
LD A, (DE)
|
||||
CP A, (HL)
|
||||
|
||||
; return NZ if they're not equal
|
||||
RET NZ
|
||||
|
||||
; next character
|
||||
DEC D
|
||||
INC H
|
||||
|
||||
; :clap: :clap: next meme
|
||||
DEC C
|
||||
JR NZ, h_loop_in
|
||||
hq
|
||||
|
||||
; HALT
|
||||
|
||||
;; go to next line
|
||||
INC E
|
||||
INC L
|
||||
|
||||
DEC B ; dec the loop counter and loop if negative
|
||||
JP NZ, h_loop_out
|
||||
hq2
|
||||
|
||||
XOR A ; set zero flag and return
|
||||
RET
|
||||
|
||||
CHECK_MAP:
|
||||
; B is width, C is height
|
||||
|
||||
LD A, B
|
||||
DEC A
|
||||
v_detect_loop
|
||||
|
||||
PUSH AF ; save loop count
|
||||
PUSH BC ; save width + height
|
||||
LD HL, map ; map as input
|
||||
|
||||
CALL CHECK_V_MIRROR;
|
||||
|
||||
JR NZ, v_not_it
|
||||
|
||||
POP BC
|
||||
POP AF ; fix the stack
|
||||
INC A ; for off by one errors
|
||||
OR A ; clear carry, cause it is a vert mirror
|
||||
RET
|
||||
v_not_it:
|
||||
|
||||
POP BC
|
||||
POP AF ; get values back
|
||||
|
||||
DEC A
|
||||
JP P, v_detect_loop
|
||||
|
||||
vcq
|
||||
|
||||
;; load height-1 into A
|
||||
LD A, C
|
||||
DEC A
|
||||
h_detect_loop
|
||||
|
||||
PUSH AF ; save loop count
|
||||
PUSH BC ; save width + height
|
||||
LD HL, map ; map as input
|
||||
|
||||
CALL CHECK_H_MIRROR;
|
||||
|
||||
JR NZ, h_not_it
|
||||
|
||||
POP BC
|
||||
POP AF ; fix the stack
|
||||
|
||||
INC A ; for off by one errors
|
||||
SCF ; carry, cause it is a horiz mirror
|
||||
RET
|
||||
|
||||
h_not_it:
|
||||
|
||||
POP BC
|
||||
POP AF ; fix the stack
|
||||
|
||||
DEC A
|
||||
JP P, h_detect_loop
|
||||
hcq
|
||||
|
||||
LD A, 0xFF;
|
||||
RET
|
||||
|
||||
LOAD_MAP:
|
||||
; hl: address to start of map
|
||||
; out : bc, width; height
|
||||
|
||||
LD BC, 0;
|
||||
LD DE, map ; start of map
|
||||
l_loop:
|
||||
; HALT
|
||||
|
||||
LD A, (hl) ; get character
|
||||
|
||||
;; go to next thing
|
||||
INC HL
|
||||
|
||||
CP A, 0x0A ; check if newline
|
||||
JR NZ, l_not_newline
|
||||
|
||||
;; check E is 0, break if so
|
||||
LD A, E
|
||||
OR A
|
||||
RET Z
|
||||
|
||||
;; set width to this width, increment C
|
||||
LD B, E
|
||||
|
||||
INC C
|
||||
|
||||
;; mov to beginning of next line
|
||||
LD E, 0
|
||||
INC D
|
||||
|
||||
JP l_loop;
|
||||
l_not_newline
|
||||
|
||||
LD (DE), A ; copy character
|
||||
|
||||
; go to next address
|
||||
INC E
|
||||
|
||||
; loop
|
||||
JP l_loop;
|
||||
|
||||
.org 0x6000
|
||||
map
|
||||
DEFM 'fukfukfukfukfukfukfukfukfukfuk'
|
||||
|
||||
.org 0x8000
|
||||
FILE
|
||||
INCBIN "input.txt"
|
||||
DEFB 0
|
||||
Reference in New Issue
Block a user