From 2fad402c93446ba594c6c1afe07f68e783f771cf Mon Sep 17 00:00:00 2001 From: Louis Vallat Date: Sun, 29 Dec 2024 12:22:49 +0100 Subject: [PATCH] feat: added day 19 part 1 and 2 Signed-off-by: Louis Vallat --- .gitea/workflows/build_and_run.yml | 2 +- day19/Cargo.toml | 6 +++ day19/src/main.rs | 62 ++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 day19/Cargo.toml create mode 100644 day19/src/main.rs diff --git a/.gitea/workflows/build_and_run.yml b/.gitea/workflows/build_and_run.yml index d7b1314..463a849 100644 --- a/.gitea/workflows/build_and_run.yml +++ b/.gitea/workflows/build_and_run.yml @@ -11,7 +11,7 @@ jobs: name: Challenge for day strategy: matrix: - day_number: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18] + day_number: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] runs-on: rust-bookworm steps: - name: Check out repository code diff --git a/day19/Cargo.toml b/day19/Cargo.toml new file mode 100644 index 0000000..27216fa --- /dev/null +++ b/day19/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "day19" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/day19/src/main.rs b/day19/src/main.rs new file mode 100644 index 0000000..0db337a --- /dev/null +++ b/day19/src/main.rs @@ -0,0 +1,62 @@ +use std::collections::{HashMap, HashSet}; +use std::{env, fs}; + +fn read_input(path: &str) -> String { + fs::read_to_string(path).expect("Cannot read file.") +} + +fn parse_input(input: &str) -> (HashSet<&str>, Vec<&str>) { + let mut lines = input.lines().filter(|s| !s.is_empty()); + (lines.next().unwrap().split(", ").collect(), lines.collect()) +} + +fn get_combinations( + pattern: &str, + rules: &HashSet<&str>, + combinations_counts: &mut HashMap, +) -> u64 { + if combinations_counts.contains_key(pattern) { + return *combinations_counts.get(pattern).unwrap(); + } + + let mut count = 0; + for &rule in rules { + if pattern.starts_with(rule) { + if pattern == rule { + count += 1; + } else { + let sub_pattern_combinations = + get_combinations(&pattern[rule.len()..], rules, combinations_counts); + combinations_counts + .insert(pattern[rule.len()..].to_string(), sub_pattern_combinations); + count += sub_pattern_combinations; + } + } + } + combinations_counts.insert(pattern.to_string(), count); + count +} + +fn part_1(combinations: &Vec) -> usize { + combinations.iter().filter(|&&c| c > 0).count() +} + +fn part_2(combinations: &Vec) -> u64 { + combinations.iter().sum() +} + +fn main() { + let args: Vec = env::args().collect(); + for arg in args.iter().skip(1) { + let input = read_input(&arg); + let (rules, patterns) = parse_input(&input); + let mut valid_patterns = HashMap::new(); + let combinations = patterns + .iter() + .map(|p| get_combinations(p, &rules, &mut valid_patterns)) + .collect(); + println!("[{}]", &arg); + println!("\t[Part 1] => Answer is '{}'.", part_1(&combinations)); + println!("\t[Part 2] => Answer is '{}'.", part_2(&combinations)); + } +}