From 1d285ee38c9f919669304e2b5b4f59853e65b5f4 Mon Sep 17 00:00:00 2001 From: Dominic Date: Wed, 6 Dec 2023 09:04:10 +0100 Subject: [PATCH] day 6 part 1 --- inputs/day6.txt | 2 ++ src/bin/day6.rs | 64 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 inputs/day6.txt create mode 100644 src/bin/day6.rs 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..595e431 --- /dev/null +++ b/src/bin/day6.rs @@ -0,0 +1,64 @@ +#![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 main() -> anyhow::Result<()> { + let games = read("inputs/day6.txt", parser())?; + + let mut result = 1; + 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; + } + println!("{result}"); + + Ok(()) +}