From 146735881add3e58062989d791329985ae870f98 Mon Sep 17 00:00:00 2001 From: Dominic Date: Wed, 6 Dec 2023 09:08:39 +0100 Subject: [PATCH] day 6 part 2 --- src/bin/day6.rs | 61 ++++++++++++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 24 deletions(-) diff --git a/src/bin/day6.rs b/src/bin/day6.rs index 595e431..3601de8 100644 --- a/src/bin/day6.rs +++ b/src/bin/day6.rs @@ -30,35 +30,48 @@ fn parser() -> impl Parser, Error = Simple> { .then_ignore(end()) } +fn ways2win(t: i64, d: i64) -> i64 { + // we want the minimum a s.t. (t-a)*a > d, + // and the maximum a s.t. (t-a)*a < d + // that means we have a quadratic function -a² + ta - d and we want to find + // its intersections with the axis + + let discriminant = t * t - 4 * d; + if discriminant < 0 { + return 0; + } + let sqrt = (discriminant as f64).sqrt(); + let min = ((t as f64 - sqrt) / 2.0).ceil() as i64; + let max = ((t as f64 + sqrt) / 2.0).floor() as i64; + eprintln!( + "t={t}, d={d}, min={min} ({}), max={max} ({})", + (t - min) * min, + (t - max) * max + ); + assert!(max >= min); + + max - min + 1 +} + fn main() -> anyhow::Result<()> { let games = read("inputs/day6.txt", parser())?; - let mut result = 1; + println!( + "{}", + games + .iter() + .map(|game| ways2win(game.time, game.distance)) + .product::() + ); + + let mut t = 0; + let mut d = 0; for game in &games { - let t = game.time; - let d = game.distance + 1; - // we want the minimum a s.t. (t-a)*a > d, - // and the maximum a s.t. (t-a)*a < d - // that means we have a quadratic function -a² + ta - d and we want to find - // its intersections with the axis - - let discriminant = t * t - 4 * d; - if discriminant < 0 { - continue; - } - let sqrt = (discriminant as f64).sqrt(); - let min = ((t as f64 - sqrt) / 2.0).ceil() as i64; - let max = ((t as f64 + sqrt) / 2.0).floor() as i64; - eprintln!( - "t={t}, d={d}, min={min} ({}), max={max} ({})", - (t - min) * min, - (t - max) * max - ); - assert!(max >= min); - - result *= max - min + 1; + t = t * 10i64.pow((game.time as f64).log10().floor() as u32 + 1) + game.time; + d = d * 10i64.pow((game.distance as f64).log10().floor() as u32 + 1) + + game.distance; } - println!("{result}"); + println!("{}", ways2win(t, d)); Ok(()) }