static DAY: u8 = 7; fn main() { let input = advent::read_lines(DAY); println!("{DAY}a: {}", calibration_result(&input, false)); println!("{DAY}b: {}", calibration_result(&input, true)); } fn calculateable(result: i64, operands: &[i64], with_concat: bool) -> bool { if operands.len() == 1 { return result == operands[0]; } let rem = &operands[..=operands.len()-2]; let op = operands[operands.len()-1]; if with_concat { let result_str = result.to_string(); let op_str = op.to_string(); if result_str.ends_with(&op_str) && result_str.len() > op_str.len() { let result_str = result_str.chars().take(result_str.len() - op_str.len()).collect::(); let result = result_str.parse::().unwrap(); if calculateable(result, rem, with_concat) { return true; } } } ((result - op >= 0) && calculateable(result - op, rem, with_concat)) || (result % op == 0 && calculateable(result / op, rem, with_concat)) } fn calibration_result(input: &[String], with_concat: bool) -> i64 { let mut sum = 0; for line in input { let (result, operands) = line.split_once(": ").unwrap(); let result = result.parse::().unwrap(); let operands = operands.split(" ").map(|x| x.parse::().unwrap()).collect::>(); if calculateable(result, &operands, with_concat) { sum += result; } } sum } #[cfg(test)] mod tests { use super::*; #[test] fn test() { let input = [ "190: 10 19", "3267: 81 40 27", "83: 17 5", "156: 15 6", "7290: 6 8 6 15", "161011: 16 10 13", "192: 17 8 14", "21037: 9 7 18 13", "292: 11 6 16 20", ].iter().map(|&x| String::from(x)).collect::>(); assert_eq!(calibration_result(&input, false), 3749); assert_eq!(calibration_result(&input, true), 11387); } }