diff --git a/day-13/src/main.rs b/day-13/src/main.rs index be4bd15..0a97ad2 100644 --- a/day-13/src/main.rs +++ b/day-13/src/main.rs @@ -9,7 +9,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> { println!("{}", (arrival - time) * earliest); // Part 2 - let timestamp = find_gauss(&ids); + let timestamp = find_incrementing(&ids); println!("{}", timestamp); Ok(()) @@ -28,7 +28,7 @@ fn parse_notes(input: &str) -> Result<(u32, Vec<u32>), &str> { .next() .ok_or("Input too short")? .split(',') - .map(|id| id.parse().unwrap_or(1)) + .map(|id| id.parse().unwrap_or(0)) .collect(); Ok((estimate, ids)) @@ -36,7 +36,7 @@ fn parse_notes(input: &str) -> Result<(u32, Vec<u32>), &str> { fn find_closest_bus(time: u32, ids: &Vec<u32>) -> (u32, u32) { ids.iter() - .filter(|id| **id != 1) + .filter(|id| **id != 0) .map(|id| { let mut arrival = *id; @@ -50,39 +50,48 @@ fn find_closest_bus(time: u32, ids: &Vec<u32>) -> (u32, u32) { .expect("Must have at least one bus ID") } -fn find_gauss(ids: &Vec<u32>) -> u128 { +fn find_incrementing(ids: &Vec<u32>) -> u128 { let ids: Vec<u128> = ids.iter().map(|id| *id as u128).collect(); - let product: u128 = ids.iter().product(); + let (largest, increment) = ids + .iter() + .enumerate() + .max_by_key(|id| id.1) + .expect("Must have at least one bus ID"); - let gauss = |mut n: u128, mut d: u128, m: u128| -> u128 { - while d != 1 { - if m == 1 { - return 0; - }; + let mut iterations = (14166999999493 - largest as u128) / increment; - let multiplier = if m > d { - m / d + (m % d != 0) as u128 + loop { + iterations += 1; + let max = increment * iterations; + + if ids.iter().enumerate().rev().all(|(i, number)| { + if *number == 0 { + true } else { - 1 - }; + let target = max - largest as u128 + i as u128; + target % number == 0 + } + }) { + break max - largest as u128; + } else { + if iterations % 100000000 == 0 { + let fun = ids + .iter() + .enumerate() + .filter(|(i, number)| { + if **number == 0 { + true + } else { + let target = max - largest as u128 + *i as u128; + target % **number == 0 + } + }) + .count(); - n = (n * multiplier) % m; - d = (d * multiplier) % m; + println!("{} - {}/{}", max - largest as u128, fun, ids.len()); + } } - - n / d - }; - - (0..ids.len()) - .map(|a| { - let b = product / ids[a]; - let bi = gauss(1, b, ids[a]); - let a = (ids[a] * a as u128 - a as u128) % ids[a] as u128; - - a * b * bi - }) - .sum::<u128>() - % product + } } #[cfg(test)] @@ -115,7 +124,7 @@ mod tests { ); let (time, ids) = parse_notes(input)?; - let timestamp = find_gauss(&ids); + let timestamp = find_incrementing(&ids); assert_eq!(timestamp, 3417); @@ -131,7 +140,7 @@ mod tests { ); let (time, ids) = parse_notes(input)?; - let timestamp = find_gauss(&ids); + let timestamp = find_incrementing(&ids); assert_eq!(timestamp, 1068781); @@ -147,7 +156,7 @@ mod tests { ); let (time, ids) = parse_notes(input)?; - let timestamp = find_gauss(&ids); + let timestamp = find_incrementing(&ids); assert_eq!(timestamp, 754018); @@ -163,7 +172,7 @@ mod tests { ); let (time, ids) = parse_notes(input)?; - let timestamp = find_gauss(&ids); + let timestamp = find_incrementing(&ids); assert_eq!(timestamp, 779210);