diff --git a/src/bin/day19/main.rs b/src/bin/day19/main.rs index b93a8f8..a1cbb11 100644 --- a/src/bin/day19/main.rs +++ b/src/bin/day19/main.rs @@ -1,3 +1,5 @@ +use ahash::{HashMap, HashMapExt}; + const ACTUAL_INPUT: &str = include_str!("../../../actual_inputs/2024/19/input.txt"); fn p1(input: &str) -> String { @@ -35,8 +37,54 @@ fn p1(input: &str) -> String { } fn p2(input: &str) -> String { - let _input = input.trim(); - "".to_string() + let (towels, patterns) = input + .trim() + .split_once("\n\n") + .expect("input has two sections"); + + let towels = towels.split(",").map(|s| s.trim()).collect::>(); + let patterns = patterns.lines().map(|s| s.trim()).collect::>(); + let mut dp: HashMap<&str, usize> = HashMap::new(); + + patterns + .into_iter() + .map(|pattern| { + fn check<'a>( + dp: &mut HashMap<&'a str, usize>, + pattern: &'a str, + towels: &[&str], + current_idx: usize, + ) -> usize { + if current_idx == pattern.len() { + 1 + } else { + let substring = &pattern[current_idx..]; + if let Some(count) = dp.get(&substring) { + *count + } else { + let count = towels + .iter() + .map(|towel| { + if pattern.len() - current_idx >= towel.len() + && pattern[current_idx..(current_idx + towel.len())] == **towel + { + check(dp, pattern, towels, current_idx + towel.len()) + } else { + 0 + } + }) + .sum::(); + + dp.insert(substring, count); + count + } + } + } + + check(&mut dp, pattern, &towels, 0) + }) + .sum::() + .to_string() } fn main() { @@ -73,12 +121,11 @@ bbrgwb #[test] fn test_p2_sample() { - assert_eq!(p2(SAMPLE_INPUT), ""); + assert_eq!(p2(SAMPLE_INPUT), "16"); } #[test] - #[ignore = "not yet implemented"] fn test_p2_actual() { - assert_eq!(p2(ACTUAL_INPUT), ""); + assert_eq!(p2(ACTUAL_INPUT), "717561822679428"); } }