-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday6.py
66 lines (52 loc) · 1.69 KB
/
day6.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
from collections import Counter, defaultdict
from advent import elf
# TIL: Good ol' binary search still does the trick
def main():
test_lines = elf.read_lines(__file__, test=True)
lines = elf.read_lines(__file__)
print("Part 1 (test):")
print(part1(test_lines))
print("Part 1:")
print(part1(lines))
print("Part 2 (test):")
print(part2(test_lines))
print("Part 2:")
print(part2(lines))
def part1(lines):
times = elf.septoi(lines[0])[1:] # Times
records = elf.septoi(lines[1])[1:] # Distances
out = 1
for total_time, record in zip(times, records):
bests = defaultdict(int) # dist: n
for hold in range(1, total_time-1):
dist = (total_time-hold) * hold
bests[dist] += 1
out *= sum(v for k, v in bests.items() if k > record)
return out
def part2(lines):
times = elf.septoi(lines[0])[1:] # Times
actual_time = int("".join([str(t) for t in times]))
records = elf.septoi(lines[1])[1:] # Distances
actual_record = int("".join([str(r) for r in records]))
def beats(n):
return ((actual_time-n) * n) > actual_record
start_mid = actual_time // 2
left_out = 0
left_ok = start_mid
while left_ok - left_out > 1:
left = ((left_ok - left_out) // 2 ) + left_out
if beats(left):
left_ok = left
else:
left_out = left
right_out = actual_time
right_ok = start_mid
while right_out - right_ok > 1:
right = ((right_out - right_ok) // 2 ) + right_ok
if beats(right):
right_ok = right
else:
right_out = right
return right_ok - left_ok + 1
if __name__ == '__main__':
main()