You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

100 lines
2.8 KiB

mod input_tools;
mod lexer;
use lexer::*;
use input_tools::*;
fn quadradic_eq(a: f64, b: f64, c: f64) -> (f64, f64) {
let term1 = -b / (2.0*a);
let term2 = b*b - 4.0*a*c;
let term3 = f64::sqrt(term2) / (2.0*a);
let sol1 = term1 - term3;
let sol2 = term1 + term3;
let left = f64::min(sol1, sol2);
let right = f64::max(sol1, sol2);
println!("Quad {}, {}, {} : {} {} {} -> ({}, {})", a, b, c, term1, term2, term3, left, right);
(f64::min(sol1, sol2), f64::max(sol1, sol2))
}
fn puzzle1(verbose: bool) {
println!("Part 1");
let mut stdin = simple_stdin();
let times = stdin.next().unwrap();
let distances = stdin.next().unwrap();
let time_toks = tokenize_line(&times);
let distance_toks = tokenize_line(&distances);
let num_extract = |x: &Token| match *x {
Token::Integer(i) => i as f64,
_ => panic!("Bad token")
};
let times: Vec<f64> = time_toks.iter().skip(2).map(num_extract).collect();
let distances: Vec<f64> = distance_toks.iter().skip(2).map(num_extract).collect();
let mut win_counts = vec![];
for idx in 0..times.len() {
let t = times[idx];
let d = distances[idx];
let (left, right) = quadradic_eq(-1.0, t, -d);
let discrete_left = f64::ceil(left + 0.01) as u32;
let discrete_right = f64::ceil(right) as u32;
win_counts.push(discrete_right - discrete_left);
}
if verbose {
println!("{:?}", times);
println!("{:?}", distances);
println!("{:?}", win_counts);
}
let products = win_counts.iter().fold(1, |acc, x| acc * x);
println!("Products: {}", products);
}
fn puzzle2(verbose: bool) {
println!("Part 2");
let mut stdin = simple_stdin();
let times = stdin.next().unwrap();
let distances = stdin.next().unwrap();
let race_time_str: String = times.chars().filter(|c| c.is_digit(10)).collect();
let distance_str: String = distances.chars().filter(|c| c.is_digit(10)).collect();
let race_time = u64::from_str_radix(&race_time_str, 10).unwrap() ;
let race_distance = u64::from_str_radix(&distance_str, 10).unwrap() as f64;
if verbose {
println!("Time: {}", race_time);
println!("Distance {}", race_distance);
}
let (left, right) = quadradic_eq(-1.0, race_time as f64, (-race_distance) as f64);
let discrete_left = f64::ceil(left + 0.01) as u32;
let discrete_right = f64::ceil(right) as u32;
let win_counts = discrete_right - discrete_left;
println!("Product: {}", win_counts);
}
fn main() {
let args = simple_args();
let verbose = args.get_flag("-v");
let part = args.get_value("-p", "1");
match part.as_str() {
"1" => puzzle1(verbose),
"2" => puzzle2(verbose),
_ => println!("Nothing to do")
}
}

Powered by TurnKey Linux.