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 sys
infile = sys.argv[1] if len(sys.argv) > 1 else "data/17_2022.txt"
data = open(infile).read().strip()
lines = [x for x in data.split("\n")]
def get_piece(t, y):
if t == 0:
return set([(2, y), (3, y), (4, y), (5, y)])
elif t == 1:
return set([(3, y + 2), (2, y + 1), (3, y + 1), (4, y + 1), (3, y)])
elif t == 2:
return set([(2, y), (3, y), (4, y), (4, y + 1), (4, y + 2)])
elif t == 3:
return set([(2, y), (2, y + 1), (2, y + 2), (2, y + 3)])
elif t == 4:
return set([(2, y + 1), (2, y), (3, y + 1), (3, y)])
else:
assert False
def move_left(piece):
if any([x == 0 for (x, y) in piece]):
return piece
return set([(x - 1, y) for (x, y) in piece])
def move_right(piece):
if any([x == 6 for (x, y) in piece]):
return piece
return set([(x + 1, y) for (x, y) in piece])
def move_down(piece):
return set([(x, y - 1) for (x, y) in piece])
def move_up(piece):
return set([(x, y + 1) for (x, y) in piece])
def show(r):
max_y = max([y for (x, y) in r])
for y in range(max_y, 0, -1):
row = ""
for x in range(7):
if (x, y) in r:
row += "#"
else:
row += " "
print(row)
r = set([(x, 0) for x in range(7)])
def signature(r):
max_y = max([y for (x, y) in r])
return frozenset([(x, max_y - y) for (x, y) in r if max_y - y <= 30])
l = 1000000000000
seen = {}
top = 0
i = 0
t = 0
added = 0
while t < l:
piece = get_piece(t % 5, top + 4)
while True:
if data[i] == "<":
piece = move_left(piece)
if piece & r:
piece = move_right(piece)
else:
piece = move_right(piece)
if piece & r:
piece = move_left(piece)
i = (i + 1) % len(data)
piece = move_down(piece)
if piece & r:
piece = move_up(piece)
r |= piece
top = max([y for (x, y) in r])
sr = (i, t % 5, signature(r))
if sr in seen and t >= 2022:
(old_t, old_y) = seen[sr]
dy = top - old_y
dt = t - old_t
amt = (l - t) // dt
added += amt * dy
t += amt * dt
assert t <= l
seen[sr] = (t, top)
break
t += 1
if t == 2022:
print(top)
print(top + added)
|