initial commit

This commit is contained in:
m
2024-12-05 15:22:04 +08:00
commit 5dbf437175
106 changed files with 20207 additions and 0 deletions

View 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.

View 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.

View 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.

View 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.

View 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.

View 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.

View 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.

View 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.

View 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.

View 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.

View 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.

View 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.

View 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.

View 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.

View 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.

View 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.

View File

@@ -0,0 +1,14 @@
{$mode objfpc}
{$RANGECHECKS ON}
program day17part1;
uses sysutils;
type
Tnode = record
x, y: int32;
end;
begin
end.

View 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;

View 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.

View 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.

View 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.

View 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.

View 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.

View 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.

View 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.

View 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.

View 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.

View 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.

View 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.

View 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.

View 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.

View 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.

View 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.
}

View 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;

View 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.

View 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.

View 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;

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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]]])

View 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]]])

View 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())])

View 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()])

View 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])]))], []))

View 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])

View 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()]])

View 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)]
])

View 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])

View 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

File diff suppressed because it is too large Load Diff

View 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