-
Notifications
You must be signed in to change notification settings - Fork 0
/
day17.py
73 lines (43 loc) · 1.62 KB
/
day17.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
import math
import collections
import json
def calculate_max_k_x(dest_x):
return math.ceil(math.sqrt(2*dest_x))
def calc_vel_from_dest_step(dest, step):
return ((2 * dest)/float(step) + step - 1)/2.0
def calc_pos_from_vel_k(init_vel, step):
return -1/2.0 * step * (step - 2 * init_vel - 1)
if __name__ == '__main__':
target = {
'x': (32, 65),
'y': (-225, -177)
}
candidates = list()
for x in range(target['x'][0], target['x'][1] + 1):
max_k = calculate_max_k_x(x)
x_vel_candidates = list()
for k in range(1, max_k + 1):
vel_x = calc_vel_from_dest_step(x, k)
if vel_x.is_integer() and k <= vel_x:
candidates.append({'vel': int(vel_x), 'k': k})
k_y_vel = collections.defaultdict(list)
for y_vel in range(target['y'][0], -target['y'][0]):
k = 1
pos = target['y'][0] + 1
while pos > target['y'][0]:
pos = calc_pos_from_vel_k(y_vel, k)
if target['y'][0] <= pos <= target['y'][1]:
k_y_vel[k].append(y_vel)
k += 1
count = 0
candidates_sort = sorted(candidates, key=lambda d: d['vel'])
valid_vels = set()
for candidate in candidates_sort:
if candidate['k'] >= candidate['vel']:
k_candidates = [k for k in k_y_vel.keys() if k >= candidate['vel']]
else:
k_candidates = [candidate['k']]
for k in k_candidates:
for y_vel in k_y_vel[k]:
valid_vels.add((candidate['vel'], y_vel))
print('Combinations: {0:d}'.format(len(valid_vels)))