use std::fs; use std::env; fn main() { println!("Hello, AoC day 07!"); let args: Vec = env::args().collect(); if args.len() != 2 { println!("wrong number of arguments!"); std::process::exit(1); } let file_path = &args[1]; let contents = fs::read_to_string(file_path).expect("Should have been able to read the file"); let mut sum_a: i128 = 0; let mut sum_b: i128 = 0; for line in contents.lines() { let (target_string, many_string) = line.split_once(":").expect("found a bad line w/o :"); let (target, many): (i128, Vec) = ( target_string.parse().expect("bad int"), many_string.trim().split(" ").map(|s| s.parse::().expect(&format!("bad int: {s}"))).collect() ); for x in 0..(1 << many.len()) { if target == equation_result_a(&many, x) { sum_a += target; break; } } for x in 0..(1 << (many.len()*2)) { if target == equation_result_b(&many, x) { sum_b += target; break; } } } println!("sum of valid targets is {sum_a}, part b is {sum_b}"); } fn equation_result_a(numbers: &[i128], bitmask: usize) -> i128 { let mut sum = numbers[0]; for i in 1..numbers.len() { sum = match (bitmask >> (i-1)) & 1 { 0 => sum + numbers[i], 1 => sum * numbers[i], _ => panic!("how did this happen"), } } return sum; } fn equation_result_b(numbers: &[i128], bitmask: usize) -> i128 { let mut sum = numbers[0]; for i in 1..numbers.len() { sum = match (bitmask >> ((i-1)*2)) & 0b11 { 0 => sum + numbers[i], 1 => sum * numbers[i], 2 => concatenate(sum, numbers[i]), 3 => { return -1; }, _ => panic!("how did this happen"), } } return sum; } fn concatenate(a: i128, b: i128) -> i128 { return (a * (10_i128).pow(b.ilog10()+1)) + b; }