From ff27ee12511c11b56cf40f91e0587430cfe5661e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20B=C3=BChler?= Date: Sun, 13 Dec 2020 11:45:07 +0100 Subject: [PATCH] day 13 --- data/day13/input | 2 ++ src/bin/day13.rs | 69 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 data/day13/input create mode 100644 src/bin/day13.rs diff --git a/data/day13/input b/data/day13/input new file mode 100644 index 0000000..36f269f --- /dev/null +++ b/data/day13/input @@ -0,0 +1,2 @@ +1000186 +17,x,x,x,x,x,x,x,x,x,x,37,x,x,x,x,x,907,x,x,x,x,x,x,x,x,x,x,x,19,x,x,x,x,x,x,x,x,x,x,23,x,x,x,x,x,29,x,653,x,x,x,x,x,x,x,x,x,41,x,x,13 diff --git a/src/bin/day13.rs b/src/bin/day13.rs new file mode 100644 index 0000000..a250d0d --- /dev/null +++ b/src/bin/day13.rs @@ -0,0 +1,69 @@ +const INPUT: &str = include_str!("../../data/day13/input"); + +struct Input { + now: i128, + bus_intervals: Vec>, +} + +impl Input { + fn parse(data: &str) -> Self { + let mut lines = data.lines(); + let now = lines.next().unwrap().parse::().unwrap(); + let bus_intervals = lines.next().unwrap().split(',').map(|part| { + if part == "x" { + None + } else { + Some(part.parse::().unwrap()) + } + }).collect(); + Self { now, bus_intervals } + } +} + +fn extended_gcd(a: i128, b: i128) -> (i128, i128, i128) { + // invariant: r == s*a + t*b + // old: .0, current: .1 + let mut r = (a as i128, b as i128); + let mut s = (1, 0); + let mut t = (0, 1); + + while r.1 != 0 { + let q = r.0 / r.1; + r = (r.1, r.0 - q * r.1); + s = (s.1, s.0 - q * s.1); + t = (t.1, t.0 - q * t.1); + } + (r.0 as i128, s.0 as i128, t.0 as i128) +} + + +fn main() { + let input = Input::parse(INPUT); + let (wait, interval) = input.bus_intervals.iter().filter_map(|&interval| { + let interval = interval?; + let wait = interval - ((input.now - 1) % interval) - 1; + Some((wait, interval)) + }).min().unwrap(); + println!("Waiting {} minutes for bus {}: {}", wait, interval, wait * interval); + + // searching T: T == offset (mod interval) + let mut offs_interval: Vec<(i128, i128)> = input.bus_intervals.iter().enumerate().filter_map(|(ndx, &interval)| { + let interval = interval?; + // T + ndx == 0 (mod interval) + // => offset == -ndx (mod interval) + let offset = (interval - (ndx as i128) % interval) % interval; + Some((offset, interval)) + }).collect(); + // println!("{:?}", offs_interval); + let start = offs_interval.remove(0); + let result = offs_interval.into_iter().fold(start, |(a_off, a_int), (b_off, b_int)| { + let (g, s, t) = extended_gcd(a_int, b_int); + assert_eq!(a_off % g, b_off % g); + let ai = a_int / g; + let bi = b_int / g; + let next_int = ai * bi * g; + let next_off = a_off * t * bi + b_off * s * ai; + ((next_off % next_int + next_int) % next_int, next_int) + }); + println!("Requested pattern occurs at: {}", result.0); +}