123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566 |
- lines = []
- with open("13.input") as f:
- for line in f.readlines():
- lines.append(line.strip())
- busses = [int(x) for x in lines[1].split(",") if x != "x"]
- my_time = int(lines[0])
- times = [x - my_time % x for x in busses]
- my_bus = busses[times.index(min(times))]
- print("Answer 1: {}".format(my_bus * min(times)))
- busses = [(- i % int(x), int(x)) for (i, x) in enumerate(lines[1].split(",")) if x != "x"]
- def print_table(start, busses):
- end = start + busses[-1][0]
- for i in range(start, end):
- print("{}: ".format(i), end='')
- for (offset, interval) in busses:
- if i % interval == 0:
- print('D', end='')
- else:
- print('.', end='')
- print("")
- # Stolen from: https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm#Pseudocode
- def extended_gcd(a, b):
- (old_r, r) = (a, b)
- (old_s, s) = (1, 0)
- (old_t, t) = (0, 1)
- while r != 0:
- quotient = int(old_r / r)
- (old_r, r) = (r, old_r - quotient * r)
- (old_s, s) = (s, old_s - quotient * s)
- (old_t, t) = (t, old_t - quotient * t)
- return (old_s, old_t)
- def combo(pair1, pair2):
- off1, int1 = pair1
- off2, int2 = pair2
- # This is fine since all IDs are primes
- new_int = int1 * int2
- # Find the smallest solution to
- # int1 * x + off1 = int2 * y + off2
- # int1 * x - int2 * y = 1 * (off2 - off1)
- x, y = extended_gcd(int1, -int2)
- # Correct signs
- if int1 * x - int2 * y != 1:
- x = -x
- y = -y
- x *= (off2 - off1)
- y *= (off2 - off1)
- assert int1 * x + off1 == int2 * y + off2
- return ((int1 * x + off1) % new_int, new_int)
- result_busses = list(busses)
- while len(result_busses) > 1:
- result_busses = [combo(result_busses[0], result_busses[1])] + result_busses[2:]
- print("Answer 2: {}".format(result_busses[0][0]))
|