Skip to content

Commit 8fe903c

Browse files
committed
Add solution to 2023-12-21
1 parent 2cbd5bb commit 8fe903c

File tree

2 files changed

+207
-0
lines changed

2 files changed

+207
-0
lines changed

2023/day21/input

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
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+
.................................................................S.................................................................
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+
.....#......#.......#....................#.......#..#...####.##....#...#.#.......##...#.#...........#..............#..........#....
101+
..#.........#........##....#.............##.#.#.........#....##........#..#........................#...#.#..#....#.................
102+
.#....#..#.##.......#..#..#...##............##.##..#..#......#.##.......#.................#......................##.....#........#.
103+
..................#.........#............#...##......................#...............#...........#................#.....#....#.#...
104+
..#......##............#.......#.#................#.....#..........................#..#...................#....#....#.........#....
105+
.#.#........#....#..##..#.....#.#...............#.......##..#.........#.....#........#...............##............................
106+
..#.........##...................#.#........##......#.#.......##......##.#..#....#.#.#...........#..##...................#.......#.
107+
....#.#.##.....###..#..........#....#..............#.###....#......##.............##...........#........#...........#...........##.
108+
.#...##..#......##....#........##.#..............#.......##..#.....#....##.....................#...##..#............#..........#...
109+
....#...#..........#...........#.#.#..............##.#.#.....###..................#.............#....#.....####....................
110+
........#..#.........###........................#.#..#..........#.............................#...#......#.............##..........
111+
.....#...#.............#.....#....#...#..............##.##........#..#...##.....#...............#..............#....#...#....#.....
112+
....#.#...........#...#.##.....##....#.#...........##....#.....#...............................#.#.#...#.....#..#........#.........
113+
...##...........................##..##.................##....#........#.....#...........#....#.....#............##.......#.........
114+
............#.....#.....#......##...........................................#.........#.....#......#............#........#.#.#.....
115+
......##...#....#...#...#.......#...........................#..#...#.#................#..........#...#.##..........#....##.#.......
116+
.....#...#.#..###.#.#.........#.#..........#...........#.....#.............................#..#.#....#.#.....#.....#..#......#.....
117+
.#.....#...#....................#...............................#.....#.............#.##.....####..##.....#.###....#..#............
118+
....#...#.............#.#....#.....#..#..#...#.............#.......................#.#........#..#...#.................#...#.#...#.
119+
..........#..#...#.....#..........#...#....#.#.....................#............................#....#.#......#.#.............#....
120+
..##.....#...#......#.#....#....#.##.#....#......#........##........#...........#..#........#......#.#.....................#.#.....
121+
......#...####.......#......#..##..###.......#...............#........#.........#....#.#.............##........##..#.#......#......
122+
....##.##..........#.#.#.#.#..#.....##......................#.....#.#......................#....#.................#...........#....
123+
.......#..##.#.#..##...#...........................#............................#....##.......#........#......#..........#.#.......
124+
.....#.##.......#................#...#........#...#.............................#..#........#......###.###....#...##.............#.
125+
.......#............##..........##..#.#.....#...................#................................#..#...#...#........#....#......#.
126+
.#.#.#.#..#...#...........#.#.....#...................#.#......................#......##.....#..................#...##..#.#........
127+
............#...............#...#........##....#..#...........................#.#..#.....#.##.................#...#....#......#....
128+
.....#.......#.............................#......#..#.#..#.....................#...........#...#........#.#........#....#.........
129+
.#.##..#............#..#.................................................#...#..###................##........##.#..#......#......#.
130+
.........#...............##......#............#.....#...........................#.............##.#.#.#.......###.....#..........#..
131+
...................................................................................................................................

2023/day21/solutions.py

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
from collections import deque
2+
3+
from scipy.optimize import curve_fit
4+
5+
with open("input") as f:
6+
ls = f.read().strip().split()
7+
8+
N = len(ls)
9+
blocked = set()
10+
for i, l in enumerate(ls):
11+
for j, x in enumerate(l):
12+
if x == "S":
13+
start = i + 1j * j
14+
elif x == "#":
15+
blocked.add(i + 1j * j)
16+
17+
18+
def counts():
19+
q = deque([(start, 0)])
20+
curr_dist = None
21+
evens = 1
22+
odds = 0
23+
seen = {start}
24+
while True:
25+
z, dist = q.popleft()
26+
if dist != curr_dist:
27+
curr_dist = dist
28+
yield (curr_dist, odds if curr_dist % 2 else evens)
29+
for dz in (-1, 1, -1j, 1j):
30+
w = z + dz
31+
w_mod_N = (w.real % N) + 1j * (w.imag % N)
32+
if w_mod_N in blocked or w in seen:
33+
continue
34+
seen.add(w)
35+
q.append((w, dist + 1))
36+
if dist % 2:
37+
evens += 1
38+
else:
39+
odds += 1
40+
41+
42+
# For part 2, by looking at how the output of counts evolves for the test input,
43+
# one quickly finds that it has behavior periodic with the size of the grid. By
44+
# looking at the counts for each remainder, one finds that they are all quadratic
45+
# polynomials after some initial noise. (This is easiest to see for the test input
46+
# by looking at the counts that show up after all numbers of steps that are 0 mod 11.
47+
# As such, we keep track of the counts for the residue class belong to our target,
48+
# fit a quadratic polynomial, and once the predictions have stabilized for the
49+
# actual input, we assume that we have the right answer.
50+
def f(x, a, b, c):
51+
return a * x**2 + b * x + c
52+
53+
54+
gen = counts()
55+
to_hit = 26501365
56+
period = N
57+
preds = []
58+
data = []
59+
for i, num_locs in gen:
60+
# Part 1
61+
if i == 64:
62+
print(num_locs)
63+
# Part 2
64+
if i % period == to_hit % period:
65+
data.append((i, num_locs))
66+
if len(data) < 3:
67+
continue
68+
last_seen = data[-3:]
69+
fa, fb, fc = curve_fit(f, *zip(*last_seen))[0]
70+
pred = round(f(to_hit, fa, fb, fc))
71+
preds.append(pred)
72+
# We assume that we have converged if the same prediction shows up
73+
# three times in a row
74+
if len(preds) > 3 and len(set(preds[-3:])) == 1:
75+
print(preds[-1])
76+
break

0 commit comments

Comments
 (0)