72 lines
2.0 KiB
Rust
72 lines
2.0 KiB
Rust
use std::fs;
|
|
use std::env;
|
|
|
|
fn main() {
|
|
println!("Hello, AoC day 07!");
|
|
|
|
let args: Vec<String> = 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<i128>) = (
|
|
target_string.parse().expect("bad int"),
|
|
many_string.trim().split(" ").map(|s| s.parse::<i128>().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;
|
|
} |