diff --git a/day-07/Cargo.lock b/day-07/Cargo.lock new file mode 100644 index 0000000..fe8fa1a --- /dev/null +++ b/day-07/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "day-07" +version = "0.1.0" diff --git a/day-07/Cargo.toml b/day-07/Cargo.toml new file mode 100644 index 0000000..daf428a --- /dev/null +++ b/day-07/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "day-07" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/day-07/src/main.rs b/day-07/src/main.rs new file mode 100644 index 0000000..a445210 --- /dev/null +++ b/day-07/src/main.rs @@ -0,0 +1,78 @@ +const INPUT: &str = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/input.txt")); + +fn main() { + + let eqns = INPUT.lines().map(|line| { + let (test, operands) = line.split_once(':').unwrap(); + let test = test.parse::().unwrap(); + let operands = operands + .trim_start_matches(':') + .split_whitespace() + .map(|num| num.parse::().unwrap()) + .collect::>(); + (test, operands) + }); + + { + let mut total = 0; + + for (test, operands) in eqns.clone() { + if let Some((start, rest)) = operands.split_first() { + total += u64::from(check_matches(*start, test, rest, false)) * test; + } + } + println!("Part 1: {}", total); + } + + { + let mut total = 0; + + for (test, operands) in eqns { + if let Some((start, rest)) = operands.split_first() { + total += u64::from(check_matches(*start, test, rest, true)) * test; + } + } + println!("Part 2: {}", total); + } +} + + +fn check_matches(curr: u64, test: u64, operands: &[u64], include_concat: bool) -> bool { + match operands.split_first() { + Some((first, rest)) => { + check_matches(curr + first, test, rest, include_concat) + || check_matches(curr * first, test, rest, include_concat) + || (include_concat && check_matches(concat(curr, *first), test, rest, include_concat)) + } + None => { + curr == test + } + } +} + +fn concat(left: u64, right: u64) -> u64 { + left * 10u64.pow(digits(right)) + right +} + +pub (crate) fn digits(mut number: u64) -> u32 { + if number < 100 { + if number < 10 { + 1 + } else { + 2 + } + } else if number < 1000 { + 3 + } else if number < 10000 { + 4 + } else { + number /= 10000; + let mut digits = 4; + while number != 0 { + number /= 10; + digits += 1; + } + digits + } +} + diff --git a/day-07/src/out.txt b/day-07/src/out.txt new file mode 100644 index 0000000..35b81c3 --- /dev/null +++ b/day-07/src/out.txt @@ -0,0 +1 @@ +Part 1: 456565678667482