use aoc_runner_derive::{aoc, aoc_generator}; #[derive(Debug)] pub struct BusInfo { earliest: u64, busses: Vec, } type Data = BusInfo; #[aoc_generator(day13)] pub fn input_generator(input: &str) -> Data { let mut l = input.lines(); let earliest = l.next().unwrap().parse().unwrap(); let busses = l .next() .unwrap() .split(',') .map(|c| match c { "x" => 0, n => n.parse().unwrap(), }) .collect(); BusInfo { earliest, busses } } #[aoc(day13, part1)] pub fn solve_part1(input: &Data) -> usize { let e = input.earliest; let mut min = std::u64::MAX; let mut min_id = 0; for n in &input.busses { if *n == 0 { continue; } let m = n - (e % n); if m < min { min = m; min_id = *n; } } return min as usize * min_id as usize; } #[aoc(day13, part2)] pub fn solve_part2(input: &Data) -> i64 { let b = input .busses .iter() .enumerate() .filter(|(_, n)| **n != 0) .map(|(a, b)| (a as i64, *b as i64)) .collect::>(); let mut t = 0; let target: i64 = b.iter().map(|(_, b)| b).product(); loop { let mut cnt = 0; let dt: i64 = b .iter() .filter_map(|(i, n)| { if (t + i) % n == 0 { cnt += 1; Some(*n) } else { None } }) .product(); if dt == target { return t % dt; } t += dt; } }