-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathaoc_17.py
More file actions
63 lines (53 loc) · 1.94 KB
/
aoc_17.py
File metadata and controls
63 lines (53 loc) · 1.94 KB
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
"""
Advent of Code - tentative pour J17.
Daniel Kessler (aka Dalker), le 2021.12.17
"""
from dataclasses import dataclass
from math import ceil
@dataclass
class Area:
"""An area one can be inside of or not."""
left: int
right: int
top: int
bottom: int
def __contains__(self, coords: tuple[int, int]) -> bool:
return (self.left <= coords[0] <= self.right and
self.top <= coords[1] <= self.bottom)
def get_data(fname: str) -> Area:
"""Read the day's input and return contents in adequate data structure."""
with open(f"{fname}.txt") as datafile:
line = datafile.readline().strip()
ind0, ind1 = line.find("="), line.find(",")
xmin, xmax = line[ind0+1:ind1].split("..")
ymin, ymax = line[line.find("=", ind1)+1:].split("..")
return Area(*(int(n) for n in (xmin, xmax, ymin, ymax)))
def solve(area) -> str:
"""Solve both parts of day's problem."""
# following was found with some pen and paper maths
vx0min = ceil((-1 + (1 + 8*area.left)**.5/2))
y_max = 0
n_paths = 0
for vx_init in range(vx0min, area.right + 1):
# following has *not* been optimized but works for *actual data*
for vy_init in range(area.top - 1, area.right + 1):
# pylint: disable=C0103
vx, vy = vx_init, vy_init
x, y = 0, 0
current_ymax = 0
while x <= area.right and y >= area.top:
x += vx
y += vy
vx = max(vx - 1, 0)
vy -= 1
current_ymax = max(current_ymax, y)
if (x, y) in area:
y_max = max(y_max, current_ymax)
n_paths += 1
break
return f"y_max = {y_max:4d} , n_paths = {n_paths:4d}"
if __name__ == "__main__":
hintdata = get_data("hintdata17")
realdata = get_data("input17")
print(" check hint:", solve(hintdata))
print("solve problem:", solve(realdata))