Files
adventofcode2023/day6/src/main.rs
Acvaxoort 9dafa9952f day 6
2023-12-06 14:31:24 +01:00

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);
}