-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
71 lines (51 loc) · 1.42 KB
/
main.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
def step(pos, vel):
x, y = pos
vx, vy = vel
# update
x += vx
y += vy
# drag
if vx != 0:
if vx > 0:
vx -= 1
else:
vx += 1
# gravity
vy -= 1
return (x, y), (vx, vy)
def hit(pos, target):
x, y = pos
tx, ty = target
return min(tx) <= x and x <= max(tx) and min(ty) <= y and y <= max(ty)
def miss(pos, target):
x, y = pos
tx, ty = target
return max(tx) < x or y < min(ty)
def parse(text):
text = text.strip("target area: ")
xs, ys = text.split(", ")
return [
[int(e) for e in xs.strip("x=").split("..")],
[int(e) for e in ys.strip("y=").split("..")],
]
target = parse("target area: x=244..303, y=-91..-54")
max_height_all = -float("inf")
hit_counter = 0
# all x are positive in problem set
X = max([abs(e) for e in target[0]])
# ys can be either positive or negative
Y = max([abs(e) for e in target[1]])
for ivx in range(X + 1):
for ivy in range(-Y, Y):
pos = [0, 0]
vel = (ivx, ivy)
max_height_current = -float("inf")
while not miss(pos, target):
max_height_current = max(max_height_current, pos[1])
pos, vel = step(pos, vel)
if hit(pos, target):
max_height_all = max(max_height_all, max_height_current)
hit_counter += 1
break
print("part1", max_height_all)
print("part2", hit_counter)