-
Notifications
You must be signed in to change notification settings - Fork 0
/
14.py
93 lines (79 loc) · 2.25 KB
/
14.py
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
from AoCLibrary import *
with open("input14.txt") as f:
real_input = f.read()
import time
ROLLING_ROCK = 'O'
OPEN_SPACE = '.'
WALL = '#'
def main(a : str):
a = a.strip()
inp = AdventInput(data=a)
ret = 0
board = to_board(a)
return run_cycles(board, 1000000000)
def run_cycles(board, cycles_to_run: int):
seen = dd(list)
time_to_load = {}
repeats_every_n = None
for c in range(cycles_to_run):
if c % 100 == 0:
print(c)
for direction in range(4):
board = roll_north(board)
board = rotate90(board)
fingerprint = board_to_string(board)
current_load = get_load(board)
if fingerprint in seen:
if repeats_every_n is None:
repeats_every_n = c - seen[fingerprint][-1][0]
loop_start = seen[fingerprint][-1][0]
else:
assert time_to_load[c - repeats_every_n] == current_load
seen[fingerprint].append((c, current_load))
time_to_load[c] = current_load
if repeats_every_n is not None:
return time_to_load[((cycles_to_run - loop_start) % repeats_every_n) + loop_start - 1]
def roll_north(starting_board):
board = deepcopy(starting_board)
for y in range(len(board)):
for x in range(len(board[0])):
if board[y][x] == ROLLING_ROCK:
board[y][x] = OPEN_SPACE
roll_y = y
roll_x = x
while board[roll_y][roll_x] == OPEN_SPACE:
roll_y -= 1
if roll_y < 0:
break
roll_y += 1
board[roll_y][roll_x] = ROLLING_ROCK
return board
def get_load(board):
ret = 0
for y in range(len(board)):
for x in range(len(board[0])):
if board[y][x] == ROLLING_ROCK:
ret += len(board) - y
return ret
samp = r"""
O....#....
O.OO#....#
.....##...
OO.#O....O
.O.....O#.
O.#..O.#.#
..O..#O..O
.......O..
#....###..
#OO..#....
""".lstrip("\n")
if samp and "r" not in sys.argv:
sample_answer = main(samp)
print("sample", sample_answer)
else:
print("no sample provided")
if "s" in sys.argv:
exit()
result = main(real_input)
if result is not None:
ans(result)