AdventOfCode/2020/day13.py

43 lines
1.2 KiB
Python
Raw Normal View History

2020-12-15 19:04:28 +01:00
import math
import sys
from functools import reduce
from itertools import combinations
def main():
lines = [line.rstrip() for line in sys.stdin]
earliest = int(lines[0])
ids = map(int, filter(lambda s: s != "x", lines[1].split(",")))
# Part 1
wait_times = {i: i - (earliest % i) for i in ids}
best_id, wait = min(wait_times.items(), key=lambda item: item[1])
print("Part 1:", best_id * wait)
# Part 2
# math shit
# https://en.wikipedia.org/wiki/Chinese_remainder_theorem wtf is going on
ids = []
rems = []
for i, v in enumerate(lines[1].split(",")):
if v != "x":
# import hint: you want to use negative indices for remainders to
# use it with CRT here.
rems.append(-i)
ids.append(int(v))
# are all bus IDs co-prime?
assert all(math.gcd(a, b) == 1 for a, b in combinations(ids, 2))
# CRT
# https://www.youtube.com/watch?v=zIFehsBHB8o
N = reduce(lambda a, b: a * b, ids, 1)
x = 0
for ni, ai in zip(ids, rems):
Ni = N // ni
x += ai * Ni * pow(Ni, -1, ni)
x %= N
print("Part 2:", x)
if __name__ == "__main__":
main()