advent2022

Advent of Code 2022 Solutions
git clone https://todayiwilllaunchmyinfantsonintoorbit.com/advent2022.git
Log | Files | Refs

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:
A11/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