commit dd52ea67739b8e0b7b3409f84f6b4583e4f23a02
parent d54e9a3faec5a5e7993a85634eb62fa4c08d4f64
Author: Decay <decay@todayiwilllaunchmyinfantsonintoorbit.com>
Date: Sun, 11 Dec 2022 19:10:01 -0800
Day 11 in Algol-68
FUCK YOU FUCK YOU FUCK YOU
Diffstat:
A | 11/eleven.a68 | | | 243 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 243 insertions(+), 0 deletions(-)
diff --git a/11/eleven.a68 b/11/eleven.a68
@@ -0,0 +1,242 @@
+MODE MONKEY = STRUCT(REF FLEX[]INT items,
+ PROC(INT,INT)INT worry function,
+ INT worry value,
+ INT throw divisor,
+ INT true monkey,
+ INT false monkey);
+
+CO Allow us to add more monkeys to our monkeys CO
+OP +:= = (REF FLEX[]MONKEY list, REF REF MONKEY new) VOID:
+BEGIN
+ INT upb := UPB list;
+ REF FLEX[]MONKEY new list := HEAP FLEX[0 : upb + 1]MONKEY;
+ (new list[0:upb] := list[0:upb], new list[upb + 1] := new);
+ list := new list
+END;
+
+CO append int to flex list CO
+OP +:= = (REF FLEX []INT list, INT new) VOID:
+BEGIN
+ INT lwb := LWB list;
+ INT upb := UPB list;
+ REF FLEX[]INT new list := HEAP FLEX[lwb : upb + 1]INT;
+ (new list[lwb:upb] := list[lwb:upb], new list[upb + 1] := new);
+ list := new list
+END;
+
+PROC (INT,INT)INT add worry = (INT addend, INT old)INT: (old + addend);
+
+PROC (INT,INT)INT multiply worry = (INT multiplicand, INT old)INT: (old * multiplicand);
+
+PROC (INT,INT)INT square worry = (INT ignore, INT old)INT: (old**2);
+
+PROC REF FLEX[]MONKEY read monkeys = REF FLEX[]MONKEY:
+BEGIN
+ PROC (STRING)INT parse integer = (STRING str)INT:
+ BEGIN
+ INT int := 0;
+ FOR idx FROM LWB str TO UPB str
+ DO
+ int := (int * 10) + (ABS str[idx] - 48)
+ OD;
+ int
+ END;
+
+ FILE puzzle input;
+ REF FLEX[]MONKEY monkeys = HEAP FLEX[0:-1]MONKEY;
+
+ IF open(puzzle input, "input", stand in channel)/=0
+ THEN
+ print(("Can't open input for read", newline))
+ FI;
+
+ INT monkey index;
+ REF MONKEY new monkey;
+ on logical file end(puzzle input, (REF FILE file) BOOL: GOTO done);
+ DO
+ STRING line;
+
+ get(puzzle input, (line, newline));
+
+ IF line = "" THEN BEGIN
+ monkeys +:= new monkey;
+ END
+ ELIF line[1:6] = "Monkey"
+ THEN BEGIN
+ new monkey := HEAP MONKEY;
+ monkey index := parse integer(line[8:UPB line - 1])
+ END
+ ELIF line[3:17] = "Starting items:"
+ THEN BEGIN
+ PROC (STRING)INT find comma := (STRING input)INT:
+ BEGIN
+ INT index := 1;
+ WHILE (index < UPB input) AND (input[index] /= ",") DO
+ index +:= 1
+ OD;
+ index
+ END;
+ STRING starting items := line[19:UPB line];
+ REF FLEX[]INT items := HEAP FLEX[1:0]INT;
+ INT comma index := 1;
+ WHILE comma index <= UPB starting items
+ DO
+ comma index := find comma(starting items);
+ IF comma index < UPB starting items
+ THEN BEGIN
+ INT item value := parse integer(starting items[1:comma index - 1]);
+ items +:= item value;
+ starting items := starting items[comma index + 2:UPB starting items]
+ END
+ ELSE BEGIN
+ INT item value := parse integer(starting items[1:UPB starting items]);
+ items +:= item value;
+ starting items := "";
+ END
+ FI
+ OD;
+ IF UPB starting items > 1 THEN BEGIN
+ INT item value := parse integer(starting items);
+ items +:= item value
+ END
+ FI;
+ items OF new monkey := items
+ END
+ ELIF line[3:12] = "Operation:"
+ THEN BEGIN
+ STRING expression = line[14:UPB line];
+ CHAR op = expression[11];
+ worry function OF new monkey :=
+ IF expression[11:UPB expression] = "* old" THEN
+ worry value OF new monkey := 0;
+ square worry
+ ELSE
+ worry value OF new monkey := parse integer(expression[13:UPB expression]);
+ (op = "+" | add worry | multiply worry)
+ FI
+ END
+ ELIF line[3:7] = "Test:"
+ THEN BEGIN
+ STRING test = line[9:UPB line];
+ throw divisor OF new monkey := parse integer(test[14:UPB test]);
+ get(puzzle input, (line, newline));
+ STRING true clause := line[14:UPB line];
+ true monkey OF new monkey := parse integer(true clause[17:UPB true clause]);
+ get(puzzle input, (line, newline));
+ STRING false clause := line[15:UPB line];
+ false monkey OF new monkey := parse integer(false clause[17:UPB false clause])
+ END
+ FI
+ OD;
+ done: monkeys +:= new monkey; CO Save last monkey CO
+ close(puzzle input);
+ monkeys
+END;
+
+PROC ([]INT)INT list length = ([]INT list)INT:
+BEGIN
+ ((UPB list - LWB list) + 1)
+END;
+
+PROC (REF []INT, REF []INT)REF []INT merge lists = (REF []INT left, REF []INT right)REF []INT:
+BEGIN
+ INT total length := list length(left) + list length(right);
+ REF FLEX[]INT merged := HEAP [1:total length]INT;
+ INT left index := LWB left;
+ INT right index := LWB right;
+ INT merged index := 1;
+ WHILE (left index <= UPB left) AND (right index <= UPB right) DO
+ IF left[left index] >= right[right index] THEN
+ BEGIN
+ merged[merged index] := left[left index];
+ left index := left index + 1;
+ END
+ ELSE BEGIN
+ merged[merged index] := right[right index];
+ right index := right index + 1;
+ END
+ FI;
+ merged index := merged index + 1
+ OD;
+ IF left index <= UPB left THEN
+ merged[merged index:UPB merged] := left[left index:UPB left]
+ ELIF right index <= UPB right THEN
+ merged[merged index:UPB merged] := right[right index:UPB left]
+ FI;
+ merged
+END;
+
+PROC (REF []INT)REF []INT sort integer list = (REF []INT list)REF []INT:
+BEGIN
+ INT length = list length(list);
+ IF length <= 1 THEN
+ list
+ ELSE
+ INT mid := ((length % 2) + LWB list);
+ merge lists(sort integer list(list[LWB list:mid - 1]), sort integer list(list[mid:UPB list]))
+ FI
+END;
+
+BEGIN
+ []MONKEY monkeys = read monkeys();
+ REF []INT inspections = LOC [0:UPB monkeys]INT;
+ FOR iterations FROM 1 TO 20
+ DO
+ FOR monkey index FROM 0 TO UPB monkeys
+ DO
+ MONKEY monkey := monkeys[monkey index];
+ REF FLEX[]INT items = items OF monkey;
+ IF iterations = 1 THEN
+ inspections[monkey index] := 0
+ FI;
+ IF UPB items >= LWB items THEN
+ BEGIN
+ FOR item index FROM LWB items TO UPB items
+ DO
+ inspections[monkey index] := inspections[monkey index] + 1;
+ INT worry value := (worry function OF monkey)(worry value OF monkey, items[item index]) % 3;
+ INT throw target := ((worry value MOD throw divisor OF monkey) = 0 | true monkey OF monkey | false monkey OF monkey);
+ items OF monkeys[throw target] +:= worry value;
+ OD;
+ items OF (monkeys[monkey index]) := HEAP FLEX[1:0]INT
+ END
+ FI
+ OD
+ OD;
+
+ [1:UPB monkeys + 1]INT sorted := sort integer list(inspections);
+ print(("Monkey business (star 1): ", sorted[1] * sorted[2], new line));
+
+ []MONKEY monkeys again = read monkeys(); CO Reread because we're lazy CO
+ INT throw divisor := 1;
+ FOR i FROM 0 TO UPB monkeys again
+ DO
+ throw divisor := throw divisor * throw divisor OF monkeys again[i]
+ OD;
+ FOR iterations FROM 1 TO 10000
+ DO
+ FOR monkey index FROM 0 TO UPB monkeys again
+ DO
+ MONKEY monkey := monkeys again[monkey index];
+ REF FLEX[]INT items = items OF monkey;
+ IF iterations = 1 THEN
+ inspections[monkey index] := 0
+ FI;
+ IF UPB items >= LWB items THEN
+ BEGIN
+ FOR item index FROM LWB items TO UPB items
+ DO
+ inspections[monkey index] := inspections[monkey index] + 1;
+ INT worry value := (worry function OF monkey)(worry value OF monkey, items[item index]);
+ INT throw target := ((worry value MOD throw divisor OF monkey) = 0 | true monkey OF monkey | false monkey OF monkey);
+ items OF monkeys again[throw target] +:= worry value MOD throw divisor;
+ OD;
+ items OF (monkeys again[monkey index]) := HEAP FLEX[1:0]INT
+ END
+ FI
+ OD;
+ OD;
+
+ sorted := sort integer list(inspections);
+ print(("Monkey business (star 2): ", sorted[1] * sorted[2], new line));
+END
+\ No newline at end of file