2023 day6/rust: use integer operations
This commit is contained in:
parent
4535a4d3e7
commit
9e27a295ae
1 changed files with 18 additions and 10 deletions
|
@ -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()
|
||||
|
|
Loading…
Reference in a new issue