-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday-14.py
177 lines (140 loc) · 4.47 KB
/
day-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
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
import re
import sys
from time import sleep
import aocd
from dotenv import load_dotenv
load_dotenv()
# Set the day and year
DAY = "14"
YEAR = "2024"
INPUT_PATTERN = re.compile(r"p\=(\d+)\,(\d+) v\=(\-?\d+),(\-?\d+)")
def get_input(path):
"""Load the data from the file"""
# Open the file
with open(f"{path}/day-{DAY}.txt", "r") as f:
values = [
INPUT_PATTERN.match(line.strip()).groups()
for line in f.readlines()
]
return values
def part_1(path, submit):
"""Part 1/Star 1"""
# Get the data
data = get_input(path)
# Get the grid details
number_steps = 100
if "tests" in path:
width = 11
height = 7
print_grid = True
else:
width = 101
height = 103
print_grid = False
# For display purposes only
if print_grid:
grid = [["." for _ in range(width)] for __ in range(height)]
# Identify which quadrant the robot ends up in
quads = [0, 0, 0, 0]
for robot in data:
# Identify where the robot ends up
col, row, v_col, v_row = robot
p_col = (int(col) + number_steps * int(v_col)) % width
p_row = (int(row) + number_steps * int(v_row)) % height
# For display purposes only
if print_grid:
if grid[p_row][p_col] == ".":
grid[p_row][p_col] = 1
else:
grid[p_row][p_col] += 1
# Identify the quadrant the robot is in
if p_col < (width - 1) // 2:
if p_row < (height - 1) // 2:
quads[0] += 1
elif p_row > (height - 1) // 2:
quads[1] += 1
elif p_col > (width - 1) // 2:
if p_row < (height - 1) // 2:
quads[2] += 1
elif p_row > (height - 1) // 2:
quads[3] += 1
answer = quads[0] * quads[1] * quads[2] * quads[3]
# Print the grid (visual)
if print_grid:
grid[height // 2] = [" " for _ in range(width)]
for i in range(height):
grid[i][width // 2] = " "
for line in grid:
print("".join([str(i) for i in line]))
# Print out the response
print(f"Task 1 Answer: {answer}")
# Submit the answer
if submit:
aocd.submit(answer, part="a", day=int(DAY), year=int(YEAR))
def output_grid(robots, width, height):
grid = [["." for _ in range(width)] for __ in range(height)]
for row, col in robots:
grid[row][col] = "#"
with open(f"outputs/day-{DAY}.txt", "a") as f:
f.write("\n".join(["".join(line) for line in grid]))
def part_2(path, submit):
"""Part 2/Star 2"""
# Get the data
data = get_input(path)
with open(f"outputs/day-{DAY}.txt", "w") as f:
f.write("")
# Get the grid details
number_steps = 10000
if "tests" in path:
width = 11
height = 7
else:
width = 101
height = 103
divider = "-" * (width + 10)
# Spotted a pattern every 101 steps
for step in range(4611, number_steps, 101):
robots = set()
for robot in data:
# Identify where the robot ends up
col, row, v_col, v_row = robot
p_col = (int(col) + step * int(v_col)) % width
p_row = (int(row) + step * int(v_row)) % height
robots.add((p_row, p_col))
# For display purposes only
with open(f"outputs/day-{DAY}.txt", "a") as f:
f.write(f"\n\n{step}\n{divider}\n")
output_grid(robots, width, height)
answer = 7338 # Manually identified in file
# Print out the response
print(f"Task 2 Answer: {answer}")
# Submit the answer
if submit:
aocd.submit(answer, part="b", day=int(DAY), year=int(YEAR))
if __name__ == "__main__":
"""
Run using e.g.
`python day-14.py -test`
`python day-14.py`
`python day-14.py -submit`
`python day-14.py -test -2`
`python day-14.py -2`
`python day-14.py -test -both`
`python day-14.py -both`
"""
# Identify the folder that the input is in
test = "-test" in sys.argv
if test:
path = "input-tests"
else:
path = "inputs"
# Identify if they need to submit the answer
submit = "-test" not in sys.argv and "-submit" in sys.argv
# Identify which one to run - 1 is default
if "-2" in sys.argv:
part_2(path, submit)
elif "-both" in sys.argv:
part_1(path, submit)
part_2(path, submit)
else:
part_1(path, submit)