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.10/lib/client.js";
const INPUT = `
O....#....
O.OO#....#
.....##...
OO.#O....O
.O.....O#.
O.#..O.#.#
..O..#O..O
.......O..
#....###..
#OO..#....
`
.trim()
.split("\n")
.map((line) => line.split(""));
const PROGRAM = `
# AOC Day 14, Part 2 - Take 1
#builtin INT_MINUS minus
#builtin NAT_SUCC s
#builtin INT_PLUS plus
input X Y is Ch :-
field Root "data" is Data,
field Data Y is Row,
field Row X is Ch.
height is N :- field Root "height" is N.
width is N :- field Root "width" is N.
# PART 1: RANGE CALCULATION
# We're going to calculate all the horizontal ranges
# (hRange (pair X Y) is Width) is Height) and vertical
# ranges (vRange (pair X Y), identifying them with
# their leftmost/topmost point. We'll also create
# a lookup table for every non-blocked point:
# (hRangeFor (pair X Y) is (pair XStart Y)) and
# (vRangeFor (pair X Y) is (pair X YStart)).
# A range (horizontal or vertical) starts on any open
# space (non-#) that is at the left/top boundary or
# to the immediate right/bottom of a # symbol
growHRange (pair 0 Y) 0 :-
input 0 Y is Ch, Ch != "#".
growHRange (pair X Y) X :-
input X Y is Ch, Ch != "#",
XPrev == minus X 1,
input XPrev Y is "#".
growVRange (pair X 0) 0 :-
input X 0 is Ch, Ch != "#".
growVRange (pair X Y) Y :-
input X Y is Ch, Ch != "#",
YPrev == minus Y 1,
input X YPrev is "#".
# We grow a range whenever the next step is non-blocked
growHRange (pair XStart Y) (s X) :-
growHRange (pair XStart Y) X,
input X Y is Ch, Ch != "#".
hRangeFor (pair X Y) is (pair XStart Y) :-
growHRange (pair XStart Y) X,
input X Y is Ch, Ch != "#".
growVRange (pair X YStart) (s Y) :-
growVRange (pair X YStart) Y,
input X Y is Ch, Ch != "#".
vRangeFor (pair X Y) is (pair X YStart) :-
growVRange (pair X YStart) Y,
input X Y is Ch, Ch != "#".
# We've found the range when we get to a blocked point
# or when we get to the end.
hRange (pair X Y) is (minus XEnd X) :-
growHRange (pair X Y) XEnd,
input XEnd Y is "#".
hRange (pair X Y) is (minus width X) :-
growHRange (pair X Y) width.
vRange (pair X Y) is (minus YEnd Y) :-
growVRange (pair X Y) YEnd,
input X YEnd is "#".
vRange (pair X Y) is (minus height Y) :-
growVRange (pair X Y) height.
# PART 2: NEXT-STEP POSITION CALCULATION
# char (dir N) X Y is Ch is the key output of this calculation,
# and it means that after the Nth time you slide rocks in direction
# dir (for dir in { up, down, left, right }), the character at
# position (X, Y) will be Ch. We start with having slid everything
# to the right zero times, since right is the end of our
# up/left/down/right spin cycle
char (right 0) X Y is Ch :- input X Y is Ch.
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 15, 2023