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)]
|
#![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 {
|
fn calculate_score<I: IntoIterator<Item = (u64, u64)>>(races: I) -> u64 {
|
||||||
races
|
races
|
||||||
|
@ -11,16 +21,14 @@ fn calculate_score<I: IntoIterator<Item = (u64, u64)>>(races: I) -> u64 {
|
||||||
// x^2-tx+r = 0
|
// x^2-tx+r = 0
|
||||||
// [ x^2+px+q = 0 ==> x = -p/2±sqrt((p/2)^2-q) ]
|
// [ 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)
|
||||||
|
// x = (t ± 2 * sqrt(t^2/4-r)) / 2
|
||||||
|
// x = (t ± sqrt(t^2-4r)) / 2
|
||||||
|
|
||||||
#[allow(clippy::cast_precision_loss)]
|
let d_squared = t.pow(2) - 4 * r;
|
||||||
let t = t as f64;
|
// add a little bias for perfect squares, and subtract 1 to get the x values that lie
|
||||||
#[allow(clippy::cast_precision_loss)]
|
// inside r
|
||||||
let r = r as f64;
|
let d = isqrt(d_squared - 1) - 1;
|
||||||
|
((t - d).div(2), (t + d).div_ceil(2))
|
||||||
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)
|
|
||||||
})
|
})
|
||||||
.map(|(min, max)| max - min + 1)
|
.map(|(min, max)| max - min + 1)
|
||||||
.product()
|
.product()
|
||||||
|
|
Loading…
Reference in a new issue