2023 day6/rust: use integer operations

This commit is contained in:
Xiretza 2023-12-06 18:58:14 +00:00
parent 4535a4d3e7
commit 9e27a295ae

View file

@ -1,6 +1,16 @@
#![warn(clippy::pedantic)]
use std::io::stdin;
use std::{io::stdin, ops::Div};
#[allow(
clippy::cast_possible_truncation,
clippy::cast_sign_loss,
clippy::cast_precision_loss
)]
// FIXME: https://github.com/rust-lang/rust/issues/116226
fn isqrt(n: u64) -> u64 {
(n as f64).sqrt().floor() as u64
}
fn calculate_score<I: IntoIterator<Item = (u64, u64)>>(races: I) -> u64 {
races
@ -11,16 +21,14 @@ fn calculate_score<I: IntoIterator<Item = (u64, u64)>>(races: I) -> u64 {
// x^2-tx+r = 0
// [ x^2+px+q = 0 ==> x = -p/2±sqrt((p/2)^2-q) ]
// x = t/2 ± sqrt(t^2/4-r)
// x = (t ± 2 * sqrt(t^2/4-r)) / 2
// x = (t ± sqrt(t^2-4r)) / 2
#[allow(clippy::cast_precision_loss)]
let t = t as f64;
#[allow(clippy::cast_precision_loss)]
let r = r as f64;
let v = t / 2.0;
let w = (t.powi(2) / 4.0 - r).sqrt();
#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
((v - w + 1.0).floor() as u64, (v + w - 1.0).ceil() as u64)
let d_squared = t.pow(2) - 4 * r;
// add a little bias for perfect squares, and subtract 1 to get the x values that lie
// inside r
let d = isqrt(d_squared - 1) - 1;
((t - d).div(2), (t + d).div_ceil(2))
})
.map(|(min, max)| max - min + 1)
.product()