diff --git a/.editorconfig b/.editorconfig index 560e94b..780a4e0 100644 --- a/.editorconfig +++ b/.editorconfig @@ -15,3 +15,7 @@ trim_trailing_whitespace = false [*.md] trim_trailing_whitespace = false + +[Makefile] +indent_style = tab +tab_width = 4 diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b6f2280 --- /dev/null +++ b/Makefile @@ -0,0 +1,5 @@ +aoc_test: + cargo test --bin 07 -- --nocapture + +solve: + cargo solve 6 diff --git a/data/examples/07.txt b/data/examples/07.txt new file mode 100644 index 0000000..fc6e099 --- /dev/null +++ b/data/examples/07.txt @@ -0,0 +1,9 @@ +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 diff --git a/src/bin/07.rs b/src/bin/07.rs new file mode 100644 index 0000000..05b6e38 --- /dev/null +++ b/src/bin/07.rs @@ -0,0 +1,105 @@ +advent_of_code::solution!(7); + +pub fn part_one(input: &str) -> Option { + let mut ans = 0; + + let equations = parse_input(input); + for eq in equations { + if bt(eq.nums[0], &eq.answer, &eq.nums, 1) { + ans += eq.answer; + } + } + + Some(ans) +} + +pub fn part_two(input: &str) -> Option { + let mut ans = 0; + + let equations = parse_input(input); + for eq in equations { + if bt2(eq.nums[0], &eq.answer, &eq.nums, 1) { + ans += eq.answer; + } + } + + Some(ans) +} + +#[derive(Debug)] +struct Equation { + answer: u64, + nums: Vec, +} + +fn parse_input(input: &str) -> Vec { + let mut equations = vec![]; + for line in input.lines() { + let (answer, nums) = line.split_once(':').unwrap(); + let eq = Equation { + answer: answer.parse::().unwrap(), + nums: nums + .split_whitespace() + .map(|num| num.parse::().unwrap()) + .collect(), + }; + equations.push(eq); + } + equations +} + +fn bt(curr_val: u64, answer: &u64, nums: &Vec, i: usize) -> bool { + if curr_val > *answer { + return false; + } + if i == nums.len() { + return curr_val == *answer; + } + + let next_val = nums[i]; + + bt(curr_val * next_val, answer, nums, i + 1) || bt(curr_val + next_val, answer, nums, i + 1) +} + +fn bt2(curr_val: u64, answer: &u64, nums: &Vec, i: usize) -> bool { + if curr_val > *answer { + return false; + } + if i == nums.len() { + return curr_val == *answer; + } + + let next_val = nums[i]; + + if let Some(concat_val) = concat_nums(curr_val, &next_val) { + if bt2(concat_val, answer, nums, i + 1) { + return true; + } + } + + bt2(curr_val * next_val, answer, nums, i + 1) || bt2(curr_val + next_val, answer, nums, i + 1) +} + +fn concat_nums(num1: u64, num2: &u64) -> Option { + let new_num = num1.to_string() + &num2.to_string(); + let new_num = new_num.parse::().ok()?; + + Some(new_num) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_part_one() { + let result = part_one(&advent_of_code::template::read_file("examples", DAY)); + assert_eq!(result, Some(3749)); + } + + #[test] + fn test_part_two() { + let result = part_two(&advent_of_code::template::read_file("examples", DAY)); + assert_eq!(result, Some(11387)); + } +}