Skip to content

Commit 67f0108

Browse files
committed
day 17
1 parent 3af7bf4 commit 67f0108

File tree

3 files changed

+149
-0
lines changed

3 files changed

+149
-0
lines changed

Diff for: 17/sample-input.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
>>><<><>><<<>><>>><<<>>><<<><<<>><>><<>>

Diff for: 17/solve.py

+147
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
from itertools import cycle
2+
from sys import argv as args
3+
4+
ROCKS = [
5+
[[1, 1, 1, 1]],
6+
[
7+
[0, 1, 0],
8+
[1, 1, 1],
9+
[0, 1, 0],
10+
],
11+
[
12+
[0, 0, 1],
13+
[0, 0, 1],
14+
[1, 1, 1],
15+
],
16+
[
17+
[1],
18+
[1],
19+
[1],
20+
[1],
21+
],
22+
[
23+
[1, 1],
24+
[1, 1],
25+
]
26+
]
27+
28+
path = args[1] if len(args) >= 2 else "sample-input.txt"
29+
with open(path) as f:
30+
lines = f.read().splitlines()
31+
32+
class Rock:
33+
def __init__(self, shape):
34+
self.shape = shape
35+
def place(self, highest_y):
36+
self.x = 2
37+
self.y = len(self.shape) + 3 + highest_y
38+
def cells(self):
39+
dx = 0
40+
dy = 0
41+
for line in self.shape:
42+
for c in line:
43+
yield c, self.x + dx, self.y + dy
44+
dx += 1
45+
46+
dx = 0
47+
dy -= 1
48+
def push(self, jet, room):
49+
delta = 1 if jet == ">" else -1
50+
for c, x, y in self.cells():
51+
x += delta
52+
if c == 1 and (x > 6 or x < 0 or room[y][x]):
53+
return
54+
self.x += delta
55+
def fall(self, room):
56+
for c, x, y in self.cells():
57+
y -= 1
58+
if c == 1 and (y < 0 or room[y][x]):
59+
return True
60+
self.y -= 1
61+
return False
62+
def draw_on(self, room):
63+
for c, x, y in self.cells():
64+
if c == 1:
65+
room[y][x] = 1
66+
67+
jeti = 0
68+
rocks = cycle(ROCKS)
69+
room = [[0] * 7 for _ in range(10_000)]
70+
highest_y = -1
71+
72+
def next_jet():
73+
global jeti
74+
result = lines[0][jeti]
75+
jeti += 1
76+
jeti %= len(lines[0])
77+
return result
78+
79+
def fall():
80+
global room, highest_y
81+
82+
rock = Rock(next(rocks))
83+
rock.place(highest_y)
84+
while True:
85+
rock.push(next_jet(), room)
86+
stopped = rock.fall(room)
87+
if stopped:
88+
break
89+
rock.draw_on(room)
90+
if rock.y > highest_y:
91+
highest_y = rock.y
92+
93+
for _ in range(2022):
94+
fall()
95+
print(highest_y + 1)
96+
97+
jeti = 0
98+
rocks = cycle(ROCKS)
99+
room = [[0] * 7 for _ in range(1_000_000)]
100+
highest_y = -1
101+
102+
fingerprints = {}
103+
104+
rocks_fell = 0
105+
while rocks_fell < 1000000000000:
106+
fall()
107+
rocks_fell += 1
108+
109+
fp_jeti = jeti % len(lines[0])
110+
fp_rocks = rocks_fell % len(ROCKS)
111+
112+
hitmap = [0] * 7
113+
iy = highest_y
114+
while iy > 0:
115+
row = room[iy]
116+
for i, c in enumerate(row):
117+
hitmap[i] += c
118+
if all(c >= 1 for c in hitmap):
119+
break
120+
iy -= 1
121+
122+
if iy == 0:
123+
continue
124+
125+
fpthis = room[iy:highest_y + 1]
126+
fpkey = (fp_jeti, fp_rocks)
127+
if fpkey in fingerprints:
128+
fpold, old_rocks_fell, old_highest_y = fingerprints[fpkey]
129+
if fpold == fpthis and fpkey == (1411, 2):
130+
print(fpkey, fpold)
131+
print(old_rocks_fell, old_highest_y)
132+
print(rocks_fell, highest_y)
133+
drocks = rocks_fell - old_rocks_fell
134+
dhighest = highest_y - old_highest_y
135+
print(drocks, dhighest)
136+
can_apply = (1000000000000 - rocks_fell) // drocks
137+
rocks_fell += can_apply * drocks
138+
delta_highest = can_apply * dhighest
139+
print(rocks_fell, dhighest)
140+
#break
141+
else:
142+
if rocks_fell > 1972:
143+
fingerprints[fpkey] = fpthis, rocks_fell, highest_y
144+
145+
answer = delta_highest + highest_y + 1
146+
#assert answer == 1514285714288
147+
print(answer)

Diff for: README.md

+1
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,5 @@ Organized in a fairly self-explanatory way; `01` has the first day and so on. My
2222
| Day 14 | `00:18:18` | `00:21:25` |
2323
| Day 15 | `00:15:43` | `00:40:24` |
2424
| Day 16 | `04:06:04` | `10:09:10` |
25+
| Day 17 | `00:58:01` | `01:45:21` |
2526

0 commit comments

Comments
 (0)