use std::fs::read_to_string; use std::cmp; fn get_numbers_in_line(str: &str) -> Vec { str.split_whitespace().filter_map(|substr| substr.parse::().ok()).collect() } fn merge_numbers_in_line(str: &str) -> T where ::Err: std::fmt::Debug { str.split_whitespace() .filter(|substr| substr.parse::().ok().is_some()) .collect::>() .join("") .parse::().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::>(); let times = get_numbers_in_line::(lines[0]); let distances = get_numbers_in_line::(lines[1]); let time_fixed = merge_numbers_in_line::(lines[0]); let distance_fixed = merge_numbers_in_line::(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); }