Skip to content

Commit

Permalink
day 18 (data type is a bit too general)
Browse files Browse the repository at this point in the history
  • Loading branch information
squell committed Dec 19, 2021
1 parent 0b3fbcb commit 7fb899d
Show file tree
Hide file tree
Showing 4 changed files with 339 additions and 0 deletions.
100 changes: 100 additions & 0 deletions 18/input.txt
Original file line number Diff line number Diff line change
@@ -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]]]]
59 changes: 59 additions & 0 deletions 18/read.a68
Original file line number Diff line number Diff line change
@@ -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;
81 changes: 81 additions & 0 deletions 18/solve.a68
Original file line number Diff line number Diff line change
@@ -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))

99 changes: 99 additions & 0 deletions 18/solve2.a68
Original file line number Diff line number Diff line change
@@ -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))

0 comments on commit 7fb899d

Please sign in to comment.