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
import { Dusa } from "https://unpkg.com/dusa@0.0.11/lib/client.js";
const INPUT = `
rn=1,cm-,qp=3,cm=2,qp-,pc=4,ot=9,ab=5,pc-,pc=6,ot=7
`
.trim()
.split(',')
.map((line) => {
const label = line.split('-')[0].split('=')[0];
return {
label,
length: label.length,
ascii: label.split('').map((ch) => ch.charCodeAt(0)),
focal: line[label.length] === '-' ? null : parseInt(line.slice(label.length + 1)),
};
});
const dusa = new Dusa(`
# AOC Day 15, Part 2
#builtin INT_PLUS plus
#builtin INT_TIMES times
#builtin INT_MINUS minus
#builtin NAT_SUCC s
numBoxes is 256.
entries is N :- field _ "entries" is N.
labelLength Label is Len :-
field Ref "length" is Len,
field Ref "label" is Label.
ascii Label N is Ch :-
field _ Entry is Ref,
field Ref "label" is Label,
field Ref "ascii" is Str,
field Str N is Ch.
label Entry is Label :-
field _ Entry is Ref,
field Ref "label" is Label.
instruction Entry is del :-
field _ Entry is Ref,
field Ref "focal" is ().
instruction Entry is add N :-
field _ Entry is Ref,
field Ref "focal" is N, N != ().
# Hash computation
partialHash Label 0 is 0 :- ascii Label _ is _.
partialHash Label (s N) is Next :-
partialHash Label N is Val,
ascii Label N is Code,
X == times 17 (plus Val Code),
mod256 X is Next.
needMod256 X X :-
partialHash Label N is Val,
ascii Label N is Code,
X == times 17 (plus Val Code).
hash Label is Hash :-
partialHash Label (labelLength Label) is Hash.
# LOL, division by repeated subtraction
mod256 X is Y :-
needMod256 X Y,
Y < 256.
needMod256 X (minus Y 256) :-
needMod256 X Y,
Y >= 256.
instructionBox Box Entry Label Instr :-
label Entry is Label,
hash Label is Box,
instruction Entry is Instr.
`);
dusa.load({ data: INPUT, entries: INPUT.length }, 'field');
const instrs = Array.from({ length: 256 }).map((_, i) => []);
for (const [box, _entry, label, instr] of dusa.solution.lookup('instructionBox')) {
instrs[box].push({ label, instr });
}
const EVAL_PROGRAM = `
#builtin INT_PLUS plus
#builtin INT_TIMES times
#builtin INT_MINUS minus
#builtin NAT_SUCC s
contents 0 is nil.
Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
Comments
Nobody has commented on this val yet: be the first!
December 16, 2023