Compare commits
No commits in common. "146735881add3e58062989d791329985ae870f98" and "22ee9226c22bb57a4378bae58ac270ea15f2c8bd" have entirely different histories.
146735881a
...
22ee9226c2
2 changed files with 0 additions and 79 deletions
|
@ -1,2 +0,0 @@
|
||||||
Time: 42 68 69 85
|
|
||||||
Distance: 284 1005 1122 1341
|
|
|
@ -1,77 +0,0 @@
|
||||||
#![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 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::<i64>()
|
|
||||||
);
|
|
||||||
|
|
||||||
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(())
|
|
||||||
}
|
|
Loading…
Reference in a new issue