From 7fb899dd90ea6accb6f050bb9c3b711f83372243 Mon Sep 17 00:00:00 2001 From: Marc Schoolderman Date: Sun, 19 Dec 2021 17:33:41 +0100 Subject: [PATCH] day 18 (data type is a bit too general) --- 18/input.txt | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++ 18/read.a68 | 59 +++++++++++++++++++++++++++++ 18/solve.a68 | 81 ++++++++++++++++++++++++++++++++++++++++ 18/solve2.a68 | 99 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 339 insertions(+) create mode 100644 18/input.txt create mode 100644 18/read.a68 create mode 100644 18/solve.a68 create mode 100644 18/solve2.a68 diff --git a/18/input.txt b/18/input.txt new file mode 100644 index 0000000..1aa1391 --- /dev/null +++ b/18/input.txt @@ -0,0 +1,100 @@ +[[3,[[6,3],[9,6]]],[6,[[0,9],[9,7]]]] +[[[3,9],[[0,8],[7,6]]],[[[7,9],1],[1,3]]] +[8,[[[9,6],[8,4]],4]] +[5,[[1,2],[3,7]]] +[[[[7,7],5],[[3,5],8]],4] +[[[5,[0,7]],3],[[5,[5,3]],[1,[9,4]]]] +[[[[3,5],[7,1]],6],[[[3,6],[5,6]],[[3,2],5]]] +[[[[2,0],[3,0]],[5,7]],[[4,4],[[9,9],[9,3]]]] +[[[[8,0],7],[[7,1],9]],[[3,[8,6]],8]] +[[6,[7,5]],[[6,8],9]] +[[[9,[1,8]],2],[[[4,0],[9,3]],1]] +[[7,[1,[3,8]]],[[4,7],[8,1]]] +[[[5,5],[[4,5],[2,9]]],[[[7,7],0],8]] +[[[[4,7],3],5],[[[4,3],[3,8]],[[6,5],5]]] +[[[[3,8],2],[1,7]],[[[3,1],4],9]] +[[[[2,1],4],[[9,5],[1,4]]],[[3,5],[[9,1],9]]] +[[[6,[1,8]],[0,0]],[9,[0,3]]] +[[[[2,2],[3,3]],[[4,8],4]],[[[6,8],4],5]] +[4,[[[7,8],[3,4]],[[3,2],9]]] +[[[9,0],3],[[[7,1],4],7]] +[[[1,4],8],[[7,5],[[8,0],[0,7]]]] +[9,[[4,6],[[2,9],1]]] +[[[[1,8],8],6],[[[2,0],6],[0,5]]] +[[[5,5],[6,4]],[[3,8],[9,[7,6]]]] +[[0,[8,[1,4]]],2] +[[[[9,5],0],5],[9,[7,5]]] +[[9,[4,8]],[[8,1],[[8,6],[7,1]]]] +[4,[[[9,6],5],9]] +[[[[3,7],6],0],[[7,7],[[2,7],[9,3]]]] +[[[6,[3,7]],[[8,3],2]],[8,[6,[8,5]]]] +[[[5,[2,7]],[[6,7],3]],[5,[[4,4],1]]] +[[1,0],[[2,8],[[0,4],9]]] +[[[1,4],6],[[[9,8],[1,0]],1]] +[[3,4],[[1,[8,4]],8]] +[[[[9,4],[0,7]],[[5,4],[8,2]]],2] +[5,[[[8,7],[3,4]],[2,4]]] +[[[[1,3],[8,6]],[[3,4],6]],[[8,5],[[9,3],[5,7]]]] +[[0,[[0,9],[7,8]]],[3,9]] +[0,[[8,[2,3]],[[3,5],[4,9]]]] +[[[4,3],[[1,9],[1,5]]],[4,[[9,1],1]]] +[[[[3,6],[2,5]],3],[[8,[8,0]],[[6,9],[5,8]]]] +[7,[[3,[3,6]],[[6,9],[2,7]]]] +[[[[8,3],[6,5]],[[3,9],2]],[6,1]] +[[[2,0],[2,3]],8] +[[1,[[8,7],2]],[[[9,4],8],[4,[9,0]]]] +[[[6,7],[[5,2],3]],[[0,5],[[9,4],[2,6]]]] +[[[9,[5,8]],[[9,3],[6,9]]],5] +[[[5,[4,6]],[5,[3,2]]],[2,[9,[5,4]]]] +[8,6] +[[[4,8],[3,1]],[1,[[7,8],[7,5]]]] +[[4,[[8,8],4]],[5,[8,[3,9]]]] +[[[4,[9,0]],[[0,3],5]],[[5,[3,0]],[6,[2,3]]]] +[[[4,0],8],[[[4,0],7],[[9,6],3]]] +[[8,[[7,8],5]],[[[6,2],8],[1,[0,4]]]] +[[1,[[3,4],[0,8]]],[[6,5],3]] +[[5,2],[[8,6],[1,[9,7]]]] +[5,[6,[[1,3],[1,0]]]] +[[0,[[1,9],[5,6]]],[[[6,2],[5,1]],[[1,2],[1,0]]]] +[[[7,1],4],[[[0,3],3],[[4,8],1]]] +[[3,[9,[3,4]]],[1,[[0,0],[1,4]]]] +[1,[7,[1,[3,7]]]] +[[[0,[5,6]],[[7,4],[5,7]]],[[[6,8],[4,6]],9]] +[[[9,8],[7,[1,3]]],3] +[[[4,[0,3]],[[3,0],6]],[[2,[9,2]],1]] +[[[[1,9],[3,3]],[8,1]],5] +[[7,[5,2]],[[4,[0,1]],[3,3]]] +[[[6,6],[0,6]],[[3,[5,9]],[[4,2],[4,3]]]] +[[[7,[5,4]],[7,1]],9] +[[6,[5,2]],[[7,[0,5]],4]] +[[[8,1],[[7,6],[4,1]]],2] +[[[[4,3],[1,4]],[9,6]],[3,[[2,5],3]]] +[[[[9,3],[5,0]],1],[1,[[9,7],9]]] +[[[8,5],[5,9]],[2,[4,[0,0]]]] +[[[[7,9],2],[[8,8],[6,3]]],[7,[0,9]]] +[[[[6,6],[0,2]],[2,[9,0]]],[[0,9],[9,9]]] +[[[9,[1,3]],[6,5]],[[[1,1],8],[9,[7,2]]]] +[[8,[[8,4],6]],[[4,[5,9]],0]] +[[8,[5,[6,7]]],[[[1,9],9],[0,[0,9]]]] +[[9,[9,[7,3]]],[4,[4,7]]] +[[[[9,3],7],5],[[5,[8,5]],[0,[8,0]]]] +[[[5,[9,0]],[[7,4],[5,3]]],[3,[[1,1],[1,8]]]] +[[1,[[1,4],[5,9]]],[[[9,1],[6,5]],[9,[0,7]]]] +[[[[9,4],9],[5,3]],[[[4,2],[2,2]],[[1,0],0]]] +[[[6,[8,6]],9],[8,[[0,1],[9,7]]]] +[[2,0],[5,[[8,3],4]]] +[[[[0,2],0],8],[8,[[2,5],[8,2]]]] +[[[[7,4],8],[9,[7,5]]],[8,[7,[5,3]]]] +[[2,4],[3,[3,8]]] +[[5,4],[[0,[5,8]],[4,3]]] +[6,[[5,[4,7]],9]] +[[[2,[6,8]],[5,5]],[[[3,0],4],[[6,6],[0,1]]]] +[[[1,[4,2]],[[8,0],8]],[8,[[6,1],[0,0]]]] +[[9,[2,[3,3]]],[[2,6],[[5,2],[5,8]]]] +[[9,[4,4]],[[[8,6],1],2]] +[2,[[[0,7],7],[[7,8],5]]] +[[[4,0],[[1,1],[7,6]]],[[6,7],[[7,2],1]]] +[[[[2,5],0],[[9,5],9]],[6,[7,[6,1]]]] +[[[7,8],1],[[[6,2],0],[[9,7],[3,5]]]] +[[[9,1],0],[3,[[6,1],[6,9]]]] +[[[[9,0],0],[4,[7,0]]],[[6,[4,0]],[8,[4,2]]]] diff --git a/18/read.a68 b/18/read.a68 new file mode 100644 index 0000000..3bebf4f --- /dev/null +++ b/18/read.a68 @@ -0,0 +1,59 @@ +CO data type and some operations for snailfish numbers CO +MODE LISTELEM = STRUCT(UNION(INT,LIST) elem); +MODE LIST = REF[]LISTELEM; + +PROC make pair = (UNION(INT,LIST) x, y)LIST: + (HEAP[2]LISTELEM result; elem OF result := (x, y); result); + +PROC append = (REF LIST arr)REF UNION(INT, LIST): + (LIST(arr) IS NIL + | elem OF (arr := HEAP [1]LISTELEM)[1] CO TODO: funny bug in Algol68g if the first [1] is removed; notify Marcel. CO + | HEAP[UPB arr+1]LISTELEM fresh; fresh[1:UPB arr] := arr; arr := fresh; elem OF arr[UPB arr] + ); + +PROC dump list = (LIST data)VOID: +BEGIN + print("["); + FOR i TO UPB data DO + IF i > 1 THEN print(",") FI; + CASE elem OF data[i] IN + (INT n) : printf(($g(0)$, n)), + (LIST sub): dump list(sub) + ESAC + OD; + print("]") +END; + +PROC parse = (STRING s)LIST: +BEGIN + INT i := 1; + + PROC parse elem = UNION(INT, LIST): + IF s[i] = "[" THEN + LIST sublist := NIL; + WHILE s[i] /= "]" DO + i +:= 1; + append(sublist) := parse elem; + i +:= 1 + OD; + sublist + ELSE + INT p; char in string(s[i], p, "1234567890"); + p MOD 10 + FI; + + CASE parse elem IN + (LIST result): result + ESAC +END; + +LIST homework = BEGIN + LIST lines := NIL; + on logical file end(stand in, (REF FILE f)BOOL: done reading); + DO + STRING s; read((s)); read(new line); + append(lines) := parse(s) + OD; +done reading: + lines +END; diff --git a/18/solve.a68 b/18/solve.a68 new file mode 100644 index 0000000..1c94298 --- /dev/null +++ b/18/solve.a68 @@ -0,0 +1,81 @@ +PR include "read.a68" PR + +PROC traverse = (LIST list, PROC(INT,REF UNION(INT,LIST))BOOL visit)VOID: +BEGIN + PROC dive into = (INT depth, LIST list)VOID: + FOR i TO UPB list DO + BOOL found = visit(depth, elem OF list[i]); + CASE elem OF list[i] IN + (LIST sub): IF NOT found THEN dive into(depth+1, sub) FI + ESAC + OD; + dive into(0,list) +END; + +PROC is regular = (LIST pair)BOOL: + (BOOL result := TRUE; + FOR i TO UPB pair WHILE result DO + (elem OF pair[i] | (INT n): ~ | result := FALSE) + OD; result); + +PROC snailfish reduce = (LIST n)LIST: +BEGIN + LIST data := n; + REF UNION(INT,LIST) last regular; + INT last regular value, add to next regular; + BOOL exploded; + + PROC explode = (INT depth, REF UNION(INT,LIST) cell)BOOL: + CASE cell IN (LIST pair): + IF depth >= 3 AND is regular(pair) AND NOT exploded THEN + IF REF UNION(INT,LIST) prev cell = last regular; prev cell ISNT NIL THEN + prev cell := last regular value + (elem OF pair[1] | (INT n): n) + FI; + add to next regular := (elem OF pair[2] | (INT n): n); + cell := 0; + exploded := TRUE + ELSE FALSE + FI, + (INT n): + BEGIN + cell := n + add to next regular; + last regular := cell; + last regular value := n; + IF exploded THEN just start again FI + END + ESAC; + + PROC split = (INT depth, REF UNION(INT,LIST) cell)BOOL: + (cell | (INT n): IF n >= 10 THEN cell := make pair (n%2, (n+1)%2); just start again FI | FALSE); + +just start again: + CO dump list(data); print(new line); CO + exploded := FALSE; + last regular := NIL; + add to next regular := 0; + traverse(data, explode); + traverse(data, split); + data +END; + +PROC snailfish add = (LIST a,b)LIST: + snailfish reduce(make pair(a,b)); + +PROC snailfish abs = (LIST a)INT: +BEGIN + OP ABS = (UNION(INT,LIST) cell)INT: + CASE cell IN + (INT n): n, + (LIST pair): 3*ABS elem OF pair[1] + 2*ABS elem OF pair[2] + ESAC; + ABS a +END; + +LIST acc := (elem OF homework[1] | (LIST pair): pair); +FOR i FROM 2 TO UPB homework DO + acc := snailfish add(acc, (elem OF homework[i] | (LIST pair): pair)) +OD; + +dump list(acc); +print((snailfish abs(acc), new line)) + diff --git a/18/solve2.a68 b/18/solve2.a68 new file mode 100644 index 0000000..8fe1dea --- /dev/null +++ b/18/solve2.a68 @@ -0,0 +1,99 @@ +PR include "read.a68" PR + +PROC traverse = (LIST list, PROC(INT,REF UNION(INT,LIST))BOOL visit)VOID: +BEGIN + PROC dive into = (INT depth, LIST list)VOID: + FOR i TO UPB list DO + BOOL found = visit(depth, elem OF list[i]); + CASE elem OF list[i] IN + (LIST sub): IF NOT found THEN dive into(depth+1, sub) FI + ESAC + OD; + dive into(0,list) +END; + +PROC is regular = (LIST pair)BOOL: + (BOOL result := TRUE; + FOR i TO UPB pair WHILE result DO + (elem OF pair[i] | (INT n): ~ | result := FALSE) + OD; result); + +PROC snailfish reduce = (LIST n)LIST: +BEGIN + PROC deep copy = (LIST data)LIST: + (HEAP[UPB data]LISTELEM copy; + FOR i TO UPB data DO + (elem OF data[i] | (LIST pair): elem OF copy[i] := deep copy(pair) + | copy[i] := data[i]) + OD; + copy); + + LIST data := deep copy(n); + REF UNION(INT,LIST) last regular; + INT last regular value, add to next regular; + BOOL exploded; + + PROC explode = (INT depth, REF UNION(INT,LIST) cell)BOOL: + CASE cell IN (LIST pair): + IF depth >= 3 AND is regular(pair) AND NOT exploded THEN + IF REF UNION(INT,LIST) prev cell = last regular; prev cell ISNT NIL THEN + prev cell := last regular value + (elem OF pair[1] | (INT n): n) + FI; + add to next regular := (elem OF pair[2] | (INT n): n); + cell := 0; + exploded := TRUE + ELSE FALSE + FI, + (INT n): + BEGIN + cell := n + add to next regular; + last regular := cell; + last regular value := n; + IF exploded THEN just start again FI + END + ESAC; + + PROC split = (INT depth, REF UNION(INT,LIST) cell)BOOL: + (cell | (INT n): IF n >= 10 THEN cell := make pair (n%2, (n+1)%2); just start again FI | FALSE); + +just start again: + CO dump list(data); print(new line); CO + exploded := FALSE; + last regular := NIL; + add to next regular := 0; + traverse(data, explode); + traverse(data, split); + data +END; + +PROC snailfish add = (LIST a,b)LIST: + snailfish reduce(make pair(a,b)); + +PROC snailfish abs = (LIST a)INT: +BEGIN + OP ABS = (UNION(INT,LIST) cell)INT: + CASE cell IN + (INT n): n, + (LIST pair): 3*ABS elem OF pair[1] + 2*ABS elem OF pair[2] + ESAC; + ABS a +END; + +INT max magnitude := -1000; +LIST x1, x2; + +FOR i TO UPB homework DO FOR j TO UPB homework DO + IF i /= j THEN + INT this = snailfish abs( + snailfish add((elem OF homework[i] | (LIST pair): pair), + (elem OF homework[j] | (LIST pair): pair)) + ); + (this > max magnitude | max magnitude := this; + x1 := (elem OF homework[i] | (LIST pair): pair); + x2 := (elem OF homework[j] | (LIST pair): pair)) + FI +OD OD; + +dump list(x1); print(new line); +dump list(x2); print(new line); +print((max magnitude, new line))