diff --git a/inputs/day6.txt b/inputs/day6.txt new file mode 100644 index 0000000..57f1bf3 --- /dev/null +++ b/inputs/day6.txt @@ -0,0 +1,2 @@ +Time: 42 68 69 85 +Distance: 284 1005 1122 1341 diff --git a/src/bin/day6.rs b/src/bin/day6.rs new file mode 100644 index 0000000..3601de8 --- /dev/null +++ b/src/bin/day6.rs @@ -0,0 +1,77 @@ +#![forbid(elided_lifetimes_in_paths, unsafe_code)] + +use aoc23::read; +use chumsky::{prelude::*, text::int}; + +struct Game { + time: i64, + distance: i64 +} + +fn parser() -> impl Parser, Error = Simple> { + let int_list = just(" ") + .repeated() + .ignore_then(int(10).separated_by(just(" ").repeated().at_least(1))); + just("Time:") + .ignore_then(int_list) + .then_ignore(just("\nDistance:")) + .then(int_list) + .map(|(times, dists): (Vec, Vec)| { + times + .into_iter() + .zip(dists) + .map(|(time, distance)| Game { + time: time.parse().unwrap(), + distance: distance.parse().unwrap() + }) + .collect() + }) + .then_ignore(just("\n")) + .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())?; + + println!( + "{}", + games + .iter() + .map(|game| ways2win(game.time, game.distance)) + .product::() + ); + + let mut t = 0; + let mut d = 0; + for game in &games { + 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!("{}", ways2win(t, d)); + + Ok(()) +}