day 6 part 1
This commit is contained in:
parent
22ee9226c2
commit
1d285ee38c
2 changed files with 66 additions and 0 deletions
2
inputs/day6.txt
Normal file
2
inputs/day6.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Time: 42 68 69 85
|
||||||
|
Distance: 284 1005 1122 1341
|
64
src/bin/day6.rs
Normal file
64
src/bin/day6.rs
Normal file
|
@ -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<char, Vec<Game>, Error = Simple<char>> {
|
||||||
|
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<String>, Vec<String>)| {
|
||||||
|
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(())
|
||||||
|
}
|
Loading…
Reference in a new issue