Solve 2020/13
parent
68562a2603
commit
6c0caca1e1
@ -0,0 +1,2 @@
|
||||
1002618
|
||||
19,x,x,x,x,x,x,x,x,41,x,x,x,37,x,x,x,x,x,367,x,x,x,x,x,x,x,x,x,x,x,x,13,x,x,x,17,x,x,x,x,x,x,x,x,x,x,x,29,x,373,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,23
|
@ -0,0 +1,22 @@
|
||||
import re
|
||||
|
||||
with open('input', 'r') as f:
|
||||
arrival = int(f.readline())
|
||||
buses = list(map(int, re.findall(r'[0-9]+', f.readline().strip())))
|
||||
|
||||
earliest = None
|
||||
earliest_bus = None
|
||||
|
||||
print(f'{arrival=}')
|
||||
|
||||
for bus in buses:
|
||||
wait = bus - arrival % bus
|
||||
wait = 0 if wait == bus else wait
|
||||
if earliest is None or wait < earliest:
|
||||
earliest = wait
|
||||
earliest_bus = bus
|
||||
print(bus, wait)
|
||||
|
||||
print(f'{earliest=} {earliest_bus=}')
|
||||
print('Solution')
|
||||
print(earliest * earliest_bus)
|
@ -0,0 +1,82 @@
|
||||
"""Solution to 2020/13 part2
|
||||
|
||||
Declarations:
|
||||
t: timestamp
|
||||
bus_id, bus: used as slope (a) in the linear function
|
||||
observation: bus_ids are distinct prime numbers
|
||||
offset: postion of the bus in the list
|
||||
t + offset = arrival of bus
|
||||
normalized_offset: used so f(0) is a correct (non-negative) solution
|
||||
= -offset % bus_id
|
||||
used as intercept (b) in linear function
|
||||
bus_solution: solutions for y in the scope of one bus.
|
||||
solution: smallest y that is a solution to all linear functions
|
||||
|
||||
Functions:
|
||||
- The solutions per bus. linear (y=a*x+b)
|
||||
- t = bus_id * x + normalized_offset
|
||||
- x: natural numbers. xth solution (time of arrival - index)
|
||||
- y: solutions for t in the scope of one bus. t + delta = arrival of bus
|
||||
|
||||
Combining two functions:
|
||||
- Given y = x0 * a0 + b0
|
||||
- Given y = x1 * a1 + b1
|
||||
- x0 * a0 + b0 = x1 * a1 + b1
|
||||
- x1 = (x0 * a0 + b0 - b1) / a1
|
||||
- Remember: x0 and x1 have to be whole numbers
|
||||
- Find linear function x0 = n * a + b that describes the possible solutions
|
||||
- Let x0 be in linear function x0 = n * a + b
|
||||
- x1 = ((n * a + b) * a0 + b0 - b1) / a1
|
||||
- x1 = (n * a * a0 + a0 * b + b0 -b1) / a1
|
||||
- x1 = (n * a * a0) / a1 + (a0 * b + b0 - b1) / a1
|
||||
- For x1 to be a whole number:
|
||||
- (n * a * a0) needs to be divisible by a1
|
||||
- since a's prime factors are distinct from a1 set a = a1
|
||||
- a0 * b + b0 - b1 needs to be divisible by a1
|
||||
- find b by brute force (b = magic_number)
|
||||
- => x0 = n * a1 + magic_number
|
||||
- Apply to y = x0 * a0 + b0
|
||||
- y = (n * a1 + magic_number) * a0 + b0
|
||||
- y = n * (a0 * a1) + (a0 + b0 + magic_number)
|
||||
- new a = a0 * a1
|
||||
- new b = a0 + b0 + magic_number
|
||||
|
||||
Apply this schema recursively (or iteratively) to all functions. Each interim
|
||||
result represents a formula for all possible solutions that includes the
|
||||
processed bus_ids. At last set n = 0 (in y = n * a + b) to receive the smallest
|
||||
solution (earliest timestamp).
|
||||
"""
|
||||
|
||||
with open('input', 'r') as f:
|
||||
f.readline()
|
||||
buses = f.readline().strip().split(',')
|
||||
|
||||
departures = []
|
||||
i = 0
|
||||
for offset, bus in enumerate(buses):
|
||||
try:
|
||||
bus = int(bus)
|
||||
normalized_offset = -offset % bus
|
||||
print(f'y = x{i} * {bus:>3} + {normalized_offset:>3} ({offset=:>2})')
|
||||
departures.append((bus, normalized_offset))
|
||||
i += 1
|
||||
except ValueError:
|
||||
pass
|
||||
print()
|
||||
|
||||
a = 1
|
||||
b = 0
|
||||
for a_cur, b_cur in departures:
|
||||
magic_nr = None
|
||||
i = 0
|
||||
while magic_nr is None:
|
||||
if (a * i + b - b_cur) % a_cur == 0:
|
||||
magic_nr = i
|
||||
i += 1
|
||||
b = b + a * magic_nr
|
||||
a = a * a_cur
|
||||
print(f'y = n * {a} + {b} | {magic_nr=}')
|
||||
print()
|
||||
|
||||
print('Solution:')
|
||||
print(b)
|
Loading…
Reference in New Issue