main.rs
1 use std::str; 2 3 fn main() { 4 let mut list: Vec<(f64, Vec<f64>)> = vec![]; 5 str::from_utf8(include_bytes!("input")) 6 .unwrap() 7 .lines() 8 .map(|l| l.split(": ").collect::<Vec<&str>>()) 9 .for_each(|l| { 10 list.push(( 11 l[0].parse::<f64>().unwrap(), 12 l[1].split(" ") 13 .collect::<Vec<&str>>() 14 .iter() 15 .map(|e| e.parse::<f64>().unwrap()) 16 .collect::<Vec<f64>>(), 17 )) 18 }); 19 20 // Part 1 21 let mut correct_sum: f64 = 0.0; 22 23 let mut incorrect_lines: Vec<(f64, Vec<f64>)> = vec![]; 24 25 for line in list { 26 if is_true(line.0, &line.1) { 27 correct_sum += line.0; 28 } else { 29 incorrect_lines.push(line.clone()) 30 } 31 } 32 println!("Part 1 : {correct_sum}"); 33 34 // Part 2 35 for line in incorrect_lines { 36 if is_true_2(line.0, &line.1) { 37 dbg!("CORRECT", &line); 38 correct_sum += line.0; 39 } 40 } 41 println!("Part 2 : {correct_sum}"); 42 } 43 44 fn is_true(n: f64, l: &[f64]) -> bool { 45 if l.len() == 1 { 46 return n == l[0]; 47 } 48 49 let state = is_true(n - l.last().unwrap(), &l[..l.len() - 1]) 50 || is_true(n / l.last().unwrap(), &l[..l.len() - 1]); 51 52 return state; 53 } 54 55 fn is_true_2(n: f64, l: &[f64]) -> bool { 56 if l.len() == 1 { 57 return n == l[0]; 58 } 59 60 let state = is_true_2(n - l.last().unwrap(), &l[..l.len() - 1]) 61 || is_true_2(n / l.last().unwrap(), &l[..l.len() - 1]); 62 63 // Concat if possible 64 if n.abs() != f64::INFINITY && n.fract() == 0.0 65 && (n as u64) % (10u64.pow(l.last().unwrap().max(1.0).log10().floor() as u32 + 1)) as u64 66 == *l.last().unwrap() as u64 67 { 68 return state 69 || is_true_2( 70 (n / (10u64.pow(l.last().unwrap().max(1.0).log10().floor() as u32 + 1)) as f64) 71 .floor(), 72 &l[..l.len() - 1], 73 ); 74 } 75 76 return state; 77 }