-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathaoc2023_day14.santa
74 lines (62 loc) · 1.31 KB
/
aoc2023_day14.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
input: read("aoc://2023/14")
let transpose = |xs| zip(..xs) |> map(fold("", +))
let vertical_tilt = |direction, dish| {
dish
|> transpose
|> horizontal_tilt(direction)
|> transpose
}
let horizontal_tilt = |direction, dish| {
dish |> map |line| {
line
|> split("#")
|> map(list >> sort(direction) >> fold("", +))
|> reduce(|a, b| a + "#" + b)
}
}
let cycle = [
vertical_tilt(<),
horizontal_tilt(<),
vertical_tilt(>),
horizontal_tilt(>)
]
let spin = |dish| cycle |> fold(dish, |dish, tilt| tilt(dish))
let total_load = |dish| {
zip(1.., reverse(dish))
|> map(|[idx, row]| idx * count(_ == "O", row))
|> sum
}
part_one: {
vertical_tilt(<, lines(input))
|> total_load
}
part_two: {
let dish = lines(input)
let mut seen = #{}
let position_in_cycle = zip(1.., iterate(spin, dish)) |> find_map(|[idx, dish]| {
if seen[dish] {
let cycle_start = seen[dish]
let cycle_length = idx - cycle_start
return cycle_start + (1_000_000_000 - cycle_start) % cycle_length
}
seen = seen |> assoc(dish, idx)
return nil
})
0..position_in_cycle
|> fold(dish, spin)
|> total_load
}
test: {
input: "O....#....
O.OO#....#
.....##...
OO.#O....O
.O.....O#.
O.#..O.#.#
..O..#O..O
.......O..
#....###..
#OO..#...."
part_one: 136
part_two: 64
}