#! /usr/bin/env python3 import sys import math from typing import List from typing import Tuple def read_file(filename: str) -> Tuple[int, List[int]]: with open(filename) as f: ts = int(next(f).strip()) busses = [ int(bus) if bus != "x" else -1 for bus in next(f).strip().split(",") ] return ts, busses def read_cli(arg: str) -> List[int]: busses = [ int(bus) if bus != "x" else -1 for bus in arg.strip().split(",") ] return busses def wait_time(ts: int, bus_id: int) -> int: return (bus_id - (ts % bus_id) % bus_id) def part1(): ts, busses = read_file("input.txt") min_wait = -1 min_bus_id = 0 for bus_id in busses: if bus_id < 0: continue w = wait_time(ts, bus_id) if min_wait < 0 or w < min_wait: min_wait = w min_bus_id = bus_id print(f"Wait {min_wait} for bus {min_bus_id}. Answer {min_wait * min_bus_id}") def part2(busses=None, start=0): if busses is None: _, busses = read_file("input.txt") # busses = [7, 13, -1, -1, 59, -1, 31, 19] t = start # t = 100000000000000 # t = t - (t%7) # if t%7 != 0: # print("Not starting with multiple of 7") # return while True: # print(f"Checking time {t}") for i, bus_id in enumerate(busses): if bus_id < 0: continue if i == 0: w = t % bus_id else: w = wait_time(t, bus_id) # print(f"Wait for bus {bus_id} is {w} expect {i}") if w != i: if i > 0: t += busses[0] else: t += 1 break else: print(f"All busses match for time {t}") break def part2_calc(busses=None, start=0): if busses is None: _, busses = read_file("input.txt") # busses = [7, 13, -1, -1, 59, -1, 31, 19] t = start last_index = 0 product = -1 while True: print(f"Checking time {t}") for i, bus_id in enumerate(busses[last_index:], last_index): if bus_id < 0: continue if i == 0: w = t % bus_id else: w = wait_time(t, bus_id) print(f"Wait for bus {bus_id} is {w} expect {i}") if w == i % bus_id: last_index = i+1 if product < 0: product = bus_id else: product = product * bus_id print(f"New index {last_index}, new product {product}") else: if i > 0: t += product else: t += 1 break else: print(f"All busses match for time {t}") break if __name__ == "__main__": if len(sys.argv) == 1: part1() part2_calc() else: busses = read_cli(sys.argv[1]) b1, b2 = busses[0], busses[1] t = b1 * math.floor(b2/b1) print(f"Maybe t = {t}") start = 0 if len(sys.argv) > 2: start = int(sys.argv[2]) print("brute") part2(busses, start) print("") print("calc") part2_calc(busses, start)