From 6ec511998e5a9bda396d82bb544ad444bbc16723 Mon Sep 17 00:00:00 2001 From: pareronia <49491686+pareronia@users.noreply.github.com> Date: Sat, 7 Dec 2024 20:49:28 +0100 Subject: [PATCH] AoC 2024 Day 7 - rust --- README.md | 2 +- src/main/rust/AoC2024_07/Cargo.toml | 7 ++ src/main/rust/AoC2024_07/src/main.rs | 128 +++++++++++++++++++++++++++ src/main/rust/Cargo.lock | 7 ++ 4 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 src/main/rust/AoC2024_07/Cargo.toml create mode 100644 src/main/rust/AoC2024_07/src/main.rs diff --git a/README.md b/README.md index efb497fd..dfe39765 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ | ---| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | | python3 | [✓](src/main/python/AoC2024_01.py) | [✓](src/main/python/AoC2024_02.py) | [✓](src/main/python/AoC2024_03.py) | [✓](src/main/python/AoC2024_04.py) | [✓](src/main/python/AoC2024_05.py) | [✓](src/main/python/AoC2024_06.py) | [✓](src/main/python/AoC2024_07.py) | | | | | | | | | | | | | | | | | | | | java | [✓](src/main/java/AoC2024_01.java) | [✓](src/main/java/AoC2024_02.java) | [✓](src/main/java/AoC2024_03.java) | [✓](src/main/java/AoC2024_04.java) | [✓](src/main/java/AoC2024_05.java) | [✓](src/main/java/AoC2024_06.java) | [✓](src/main/java/AoC2024_07.java) | | | | | | | | | | | | | | | | | | | -| rust | [✓](src/main/rust/AoC2024_01/src/main.rs) | [✓](src/main/rust/AoC2024_02/src/main.rs) | [✓](src/main/rust/AoC2024_03/src/main.rs) | [✓](src/main/rust/AoC2024_04/src/main.rs) | [✓](src/main/rust/AoC2024_05/src/main.rs) | [✓](src/main/rust/AoC2024_06/src/main.rs) | | | | | | | | | | | | | | | | | | | | +| rust | [✓](src/main/rust/AoC2024_01/src/main.rs) | [✓](src/main/rust/AoC2024_02/src/main.rs) | [✓](src/main/rust/AoC2024_03/src/main.rs) | [✓](src/main/rust/AoC2024_04/src/main.rs) | [✓](src/main/rust/AoC2024_05/src/main.rs) | [✓](src/main/rust/AoC2024_06/src/main.rs) | [✓](src/main/rust/AoC2024_07/src/main.rs) | | | | | | | | | | | | | | | | | | | ## 2023 diff --git a/src/main/rust/AoC2024_07/Cargo.toml b/src/main/rust/AoC2024_07/Cargo.toml new file mode 100644 index 00000000..0b32259d --- /dev/null +++ b/src/main/rust/AoC2024_07/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "AoC2024_07" +version = "0.1.0" +edition = "2021" + +[dependencies] +aoc = { path = "../aoc" } diff --git a/src/main/rust/AoC2024_07/src/main.rs b/src/main/rust/AoC2024_07/src/main.rs new file mode 100644 index 00000000..197435fe --- /dev/null +++ b/src/main/rust/AoC2024_07/src/main.rs @@ -0,0 +1,128 @@ +#![allow(non_snake_case)] + +use aoc::Puzzle; +use std::collections::HashSet; + +#[derive(Eq, Hash, PartialEq)] +enum Op { + Add, + Multiply, + Concatenate, +} + +struct AoC2024_07; + +impl AoC2024_07 { + fn solve( + &self, + input: &::Input, + ops: &HashSet, + ) -> u64 { + fn can_obtain(sol: u64, terms: &[u64], ops: &HashSet) -> bool { + if terms.len() == 1 { + return sol == terms[0]; + } + let last = terms.last().unwrap(); + let prev_terms = &terms[..terms.len() - 1]; + if ops.contains(&Op::Multiply) + && sol % last == 0 + && can_obtain(sol.div_euclid(*last), prev_terms, ops) + { + return true; + } + if ops.contains(&Op::Add) + && sol > *last + && can_obtain(sol - *last, prev_terms, ops) + { + return true; + } + if ops.contains(&Op::Concatenate) { + let (s_sol, s_last) = (sol.to_string(), last.to_string()); + if s_sol.len() > s_last.len() && s_sol.ends_with(&s_last) { + let new_sol = &s_sol[..s_sol.len() - s_last.len()]; + if can_obtain( + new_sol.parse::().unwrap(), + prev_terms, + ops, + ) { + return true; + } + } + } + false + } + + input + .iter() + .filter(|(sol, terms)| can_obtain(*sol, terms, ops)) + .map(|(sol, _)| sol) + .sum() + } +} + +impl aoc::Puzzle for AoC2024_07 { + type Input = Vec<(u64, Vec)>; + type Output1 = u64; + type Output2 = u64; + + aoc::puzzle_year_day!(2024, 7); + + fn parse_input(&self, lines: Vec) -> Self::Input { + lines + .iter() + .map(|line| { + let (left, right) = line.split_once(": ").unwrap(); + let sol = left.parse::().unwrap(); + let terms = right + .split_whitespace() + .map(|s| s.parse::().unwrap()) + .collect(); + (sol, terms) + }) + .collect() + } + + fn part_1(&self, input: &Self::Input) -> Self::Output1 { + self.solve(input, &HashSet::from([Op::Add, Op::Multiply])) + } + + fn part_2(&self, input: &Self::Input) -> Self::Output2 { + self.solve( + input, + &HashSet::from([Op::Add, Op::Multiply, Op::Concatenate]), + ) + } + + fn samples(&self) { + aoc::puzzle_samples! { + self, part_1, TEST, 3749, + self, part_2, TEST, 11387 + }; + } +} + +fn main() { + AoC2024_07 {}.run(std::env::args()); +} + +const TEST: &str = "\ +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 +"; + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + pub fn samples() { + AoC2024_07 {}.samples(); + } +} diff --git a/src/main/rust/Cargo.lock b/src/main/rust/Cargo.lock index 226a12c9..9013ad77 100644 --- a/src/main/rust/Cargo.lock +++ b/src/main/rust/Cargo.lock @@ -433,6 +433,13 @@ dependencies = [ "indexmap", ] +[[package]] +name = "AoC2024_07" +version = "0.1.0" +dependencies = [ + "aoc", +] + [[package]] name = "aho-corasick" version = "1.0.2"