-
Notifications
You must be signed in to change notification settings - Fork 0
/
aoc2022_day21.santa
80 lines (69 loc) · 1.82 KB
/
aoc2022_day21.santa
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
input: read("aoc://2022/21")
let parse_jobs = lines >> map(split(": ")) >> dict;
let build_expression = |jobs| {
let recur = |monkey| {
match split(" ", jobs[monkey]) {
["humn"] { ["humn"] }
[const] { [int(const)] }
[lhs, op, rhs] { [recur(lhs), op, recur(rhs)] }
}
};
recur("root");
}
let evaluate = |expression| match expression {
[const] { const }
[lhs, "+", rhs] { evaluate(lhs) + evaluate(rhs) }
[lhs, "-", rhs] { evaluate(lhs) - evaluate(rhs) }
[lhs, "*", rhs] { evaluate(lhs) * evaluate(rhs) }
[lhs, "/", rhs] { evaluate(lhs) / evaluate(rhs) }
}
let contains_human? = |expression| match expression {
[const] { const == "humn" }
[lhs, _, rhs] { contains_human?(lhs) || contains_human?(rhs) }
}
let yell = |lhs, rhs| match lhs {
[x, "+", y] if contains_human?(x) { yell(x, [rhs, "-", y]) }
[x, "+", y] if contains_human?(y) { yell(y, [rhs, "-", x]) }
[x, "-", y] if contains_human?(x) { yell(x, [rhs, "+", y]) }
[x, "-", y] if contains_human?(y) { yell(y, [x, "-", rhs]) }
[x, "*", y] if contains_human?(x) { yell(x, [rhs, "/", y]) }
[x, "*", y] if contains_human?(y) { yell(y, [rhs, "/", x]) }
[x, "/", y] if contains_human?(x) { yell(x, [rhs, "*", y]) }
[x, "/", y] if contains_human?(y) { yell(y, [x, "/", rhs]) }
_ { evaluate(rhs) }
}
part_one: {
parse_jobs(input)
|> build_expression
|> evaluate;
}
part_two: {
parse_jobs(input)
|> assoc("humn", "humn")
|> build_expression
|> |[lhs, _, rhs]| yell(lhs, rhs);
}
test: {
input: "root: pppw + sjmn
dbpl: 5
cczh: sllz + lgvd
zczc: 2
ptdq: humn - dvpt
dvpt: 3
lfqf: 4
humn: 5
ljgn: 2
sjmn: drzm * dbpl
sllz: 4
pppw: cczh / lfqf
lgvd: ljgn * ptdq
drzm: hmdt - zczc
hmdt: 32"
part_one: 152
part_two: 301
}
test: {
input: read("aoc://2022/21")
part_one: 158661812617812
part_two: 3352886133831
}