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
import { Dusa } from "https://unpkg.com/dusa@0.0.10/lib/client.js";
const INPUT = `
0 3 6 9 12 15
1 3 6 10 15 21
10 13 16 21 30 45
`
.trim()
.split("\n")
.map((line) => {
const values = line
.trim()
.split(" ")
.map((n) => parseInt(n));
return {
length: values.length,
values,
};
});
const dusa = new Dusa(`
# AOC Day 9
#builtin INT_MINUS minus
#builtin INT_PLUS plus
#builtin NAT_SUCC s
# We can compute diffs from sequences...
seq Seq (plus D 1) N is (minus V2 V1) :-
needDiffs Seq D,
seq Seq D N is V1,
seq Seq D (plus N 1) is V2.
# ...and we can also compute sequences from diffs!
seq Seq D (plus N 1) is (plus V1 Delta) :-
seq Seq D N is V1,
seq Seq (plus D 1) N is Delta.
# ...in both directions!
seq Seq D N is (minus V2 Delta) :-
seq Seq D (plus N 1) is V2,
seq Seq (plus D 1) N is Delta.
# We need diffs whenever there's a non-zero value in a sequence
needDiffs Seq D :-
seq Seq D N is V,
V != 0.
# And the length of the subsequent sequence will be one shorter
len Seq (plus D 1) is Len :-
needDiffs Seq D,
len Seq D is (plus Len 1).
# allZeros Seq D tells us that diff level D of sequence #Seq
# only contains zeroes
calcAllZeroes Seq (plus D 1) 0 :- needDiffs Seq D.
calcAllZeroes Seq D (plus N 1) :- calcAllZeroes Seq D N, seq Seq D N is 0.
allZeroes Seq D :- len Seq D is Len, calcAllZeroes Seq D Len.
# If a sequence has all zeroes, we can predict the next and previous
# values, which will drive the rest of the computation
seq Seq D Len is 0 :-
allZeroes Seq D,
len Seq D is Len.
seq Seq D -1 is 0 :-
allZeroes Seq D.
# Sum up the answers
part1 0 is 0.
part1 (s N) is (plus Accum V) :-
part1 N is Accum,
len N 0 is Len,
seq N 0 Len is V.
part2 0 is 0.
part2 (s N) is (plus Accum V) :-
part2 N is Accum,
seq N 0 -1 is V.
# Derive facts from input
seq Seq 0 N is V :-
field _ Seq is Ref,
field Ref "values" is List,
field List N is V.
len Seq 0 is Len :-
field _ Seq is Ref,
field Ref "length" is Len.
`);
dusa.load(INPUT, "field");
console.log(dusa.solution!!!.get("part1", INPUT.length));
console.log(dusa.solution!!!.get("part2", INPUT.length));
Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
v3
December 9, 2023