From acfbcbea084435dcadf7888bb405052b71d9a790 Mon Sep 17 00:00:00 2001 From: Kristofers Solo Date: Sat, 7 Dec 2024 12:01:09 +0200 Subject: [PATCH] day-07 part-2 --- 2024/day-06/input1.txt.2 | 10 --- 2024/day-07/src/bin/part1.rs | 2 +- 2024/day-07/src/bin/part2.rs | 2 +- 2024/day-07/src/part1.rs | 6 +- 2024/day-07/src/part2.rs | 125 +++++++++++++++++++++++++++++++++-- 5 files changed, 123 insertions(+), 22 deletions(-) delete mode 100644 2024/day-06/input1.txt.2 diff --git a/2024/day-06/input1.txt.2 b/2024/day-06/input1.txt.2 deleted file mode 100644 index a4eb402..0000000 --- a/2024/day-06/input1.txt.2 +++ /dev/null @@ -1,10 +0,0 @@ -....#..... -.........# -.......... -..#....... -.......#.. -.......... -.#..^..... -........#. -#......... -......#... diff --git a/2024/day-07/src/bin/part1.rs b/2024/day-07/src/bin/part1.rs index c437c75..9b652e1 100644 --- a/2024/day-07/src/bin/part1.rs +++ b/2024/day-07/src/bin/part1.rs @@ -7,6 +7,6 @@ fn main() -> Result<()> { let file = include_str!("../../input1.txt"); let result = process(file).context("process part 1")?; - println!("{}", result); + println!("{result}"); Ok(()) } diff --git a/2024/day-07/src/bin/part2.rs b/2024/day-07/src/bin/part2.rs index bf28590..656b82c 100644 --- a/2024/day-07/src/bin/part2.rs +++ b/2024/day-07/src/bin/part2.rs @@ -7,6 +7,6 @@ fn main() -> Result<()> { let file = include_str!("../../input2.txt"); let result = process(file).context("process part 2")?; - println!("{}", result); + println!("{result}"); Ok(()) } diff --git a/2024/day-07/src/part1.rs b/2024/day-07/src/part1.rs index f5c7525..a41e8ff 100644 --- a/2024/day-07/src/part1.rs +++ b/2024/day-07/src/part1.rs @@ -1,8 +1,6 @@ -use std::str::FromStr; - use miette::{Diagnostic, Result}; +use std::str::FromStr; use thiserror::Error; -use tracing::Instrument; #[derive(Debug, Clone, Copy)] enum Operator { @@ -11,7 +9,7 @@ enum Operator { } impl Operator { - const fn apply(&self, a: usize, b: usize) -> usize { + const fn apply(self, a: usize, b: usize) -> usize { match self { Self::Add => a + b, Self::Multiply => a * b, diff --git a/2024/day-07/src/part2.rs b/2024/day-07/src/part2.rs index cbcdee4..bcf6fff 100644 --- a/2024/day-07/src/part2.rs +++ b/2024/day-07/src/part2.rs @@ -1,9 +1,115 @@ -use miette::Result; +use miette::{Diagnostic, Result}; +use std::str::FromStr; +use thiserror::Error; + +#[derive(Debug, Clone, Copy)] +enum Operator { + Add, + Multiply, + Concatenation, +} + +impl Operator { + fn apply(self, a: usize, b: usize) -> usize { + match self { + Self::Add => a + b, + Self::Multiply => a * b, + Self::Concatenation => format!("{a}{b}").parse::().unwrap(), + } + } + + const fn all_operators() -> [Self; 3] { + [Self::Add, Self::Multiply, Self::Concatenation] + } +} + +#[derive(Debug, Error, Diagnostic)] +enum EquationError { + #[error("Failed to parse equation")] + ParseError, + #[error("Missing value")] + MissingValue, +} + +#[derive(Debug)] +struct Equation { + result: usize, + numbers: Vec, +} + +impl Equation { + fn find_result(&self) -> Option { + fn recursive_find( + numbers: &[usize], + target: usize, + current: usize, + index: usize, + is_first: bool, + ) -> Option { + if index == numbers.len() { + return if current == target { + Some(current) + } else { + None + }; + } + let num = numbers[index]; + + for op in Operator::all_operators() { + if let Some(result) = recursive_find( + numbers, + target, + if is_first { + num + } else { + op.apply(current, num) + }, + index + 1, + false, + ) { + return Some(result); + } + } + + None + } + if self.numbers.is_empty() { + return None; + } + recursive_find(&self.numbers, self.result, 0, 0, true) + } +} + +impl FromStr for Equation { + type Err = EquationError; + fn from_str(s: &str) -> std::result::Result { + let line = s.trim().split(':').collect::>(); + let result = line + .first() + .ok_or(EquationError::MissingValue)? + .parse() + .map_err(|_| EquationError::ParseError)?; + + let numbers = line + .last() + .ok_or(EquationError::MissingValue)? + .split_whitespace() + .map(str::parse) + .collect::, _>>() + .map_err(|_| EquationError::ParseError)?; + + Ok(Self { result, numbers }) + } +} #[tracing::instrument] pub fn process(input: &str) -> Result { - todo!("day xx - part 2"); - Ok(0) + let result = input + .lines() + .map(Equation::from_str) + .filter_map(|eq| eq.ok()?.find_result()) + .sum(); + Ok(result) } #[cfg(test)] @@ -12,9 +118,16 @@ mod tests { #[test] fn test_process() -> Result<()> { - let input = ""; - todo!("haven't built test yet"); - let result = 0; + 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"; + let result = 11387; assert_eq!(process(input)?, result); Ok(()) }