47 lines
1.7 KiB
Rust
47 lines
1.7 KiB
Rust
use std::fs::read_to_string;
|
|
use std::cmp;
|
|
|
|
fn get_numbers_in_line<T: std::str::FromStr>(str: &str) -> Vec<T> {
|
|
str.split_whitespace().filter_map(|substr| substr.parse::<T>().ok()).collect()
|
|
}
|
|
|
|
fn merge_numbers_in_line<T: std::str::FromStr>(str: &str) -> T
|
|
where <T as std::str::FromStr>::Err: std::fmt::Debug {
|
|
str.split_whitespace()
|
|
.filter(|substr| substr.parse::<T>().ok().is_some())
|
|
.collect::<Vec<_>>()
|
|
.join("")
|
|
.parse::<T>().unwrap()
|
|
}
|
|
|
|
fn race_solutions(time: i64, record_distance: i64) -> i64 {
|
|
// x - time held
|
|
// distance = x * (time - x)
|
|
// solving distance > record_distance:
|
|
// x^2 - x * time + record_distance < 0
|
|
// delta = time^2 - 4 * record_distance
|
|
// solution = (time +- sqrt(delta)) / 2
|
|
let delta: f64 = (time * time - 4 * record_distance) as f64;
|
|
if delta < 0.0 {
|
|
return 0;
|
|
}
|
|
let delta_sqrt = f64::sqrt(delta);
|
|
let min_solution = f64::ceil((time as f64 - delta_sqrt) / 2.0) as i64;
|
|
let max_solution = f64::floor((time as f64 + delta_sqrt) / 2.0) as i64;
|
|
cmp::max(max_solution - min_solution + 1, 0 as i64)
|
|
}
|
|
|
|
fn main() {
|
|
let lines_str = read_to_string("input.txt").unwrap();
|
|
let lines = lines_str.lines().collect::<Vec<_>>();
|
|
let times = get_numbers_in_line::<i64>(lines[0]);
|
|
let distances = get_numbers_in_line::<i64>(lines[1]);
|
|
let time_fixed = merge_numbers_in_line::<i64>(lines[0]);
|
|
let distance_fixed = merge_numbers_in_line::<i64>(lines[1]);
|
|
let solutions1 = std::iter::zip(times, distances).fold(
|
|
1, |p, (t, d)| p * race_solutions(t, d));
|
|
let solutions2 = race_solutions(time_fixed, distance_fixed);
|
|
println!("Solutions 1: {}", solutions1);
|
|
println!("Solutions 2: {}", solutions2);
|
|
}
|