add: day19

This commit is contained in:
Charles
2025-03-23 19:02:25 -07:00
parent 81fea4984d
commit f4c6437fd6
+28 -25
View File
@@ -1,4 +1,3 @@
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use advent_of_code_2024::{make_main, SResult}; use advent_of_code_2024::{make_main, SResult};
@@ -15,43 +14,45 @@ fn solve(lines: Vec<String>) -> SResult<(usize, usize)> {
// see if we can form it using shorter patterns. If we can, ignore it. // see if we can form it using shorter patterns. If we can, ignore it.
patterns.sort_by(|a, b| a.len().cmp(&b.len())); patterns.sort_by(|a, b| a.len().cmp(&b.len()));
// Stores a mapping of 'char' => (pattern, larger_patterns) // Stores a mapping of 'char' => (pattern, larger_patterns)
let mut new_patterns: HashMap<char, Vec<(&str, HashSet<&str>)>> = HashMap::default(); let mut new_patterns: Vec<(&str, HashSet<&str>)> = Vec::new();
let mut small_patterns = HashSet::new(); let mut small_patterns = HashSet::new();
for pattern in &patterns { for pattern in &patterns {
if let Some(c) = rec(&pattern, &new_patterns, &mut memo) { if let Some(c) = rec(&pattern, &new_patterns, &mut HashMap::new()) {
*memo.entry(&pattern).or_insert(0) = c + 1; // At this point, we haven't loaded the larger patterns into the hashsets
// in the new_patterns, so we never check if it matches. We always
// add one to the computed value.
//*memo.entry(&pattern).or_insert(0) = c + 1;
} else { } else {
let start = pattern.chars().next().unwrap(); new_patterns.push((pattern, HashSet::new()));
new_patterns.entry(start).or_insert_with(Vec::new).push((pattern, HashSet::new()));
small_patterns.insert(pattern); small_patterns.insert(pattern);
} }
} }
for (_, v) in new_patterns.iter_mut() { new_patterns.sort_by(|a, b| a.0.cmp(&b.0));
v.sort_by(|a, b| a.0.cmp(&b.0));
for v in v { for v in &mut new_patterns {
for pattern in &patterns { for pattern in &patterns {
if small_patterns.contains(pattern) { if small_patterns.contains(pattern) {
continue; continue;
} }
if let Some(_) = pattern.strip_prefix(v.0) { if let Some(_) = pattern.strip_prefix(v.0) {
v.1.insert(pattern); v.1.insert(pattern);
}
} }
} }
} }
println!("Patterns: {:?}", new_patterns); // Reset the memoization
let mut memo: HashMap<&str, usize> = HashMap::default();
memo.insert("", 1);
let mut memo_vec: Vec<(&str, usize)> = memo.clone().into_iter().collect(); for pattern in &patterns {
memo_vec.sort_by(|a, b| a.0.cmp(&b.0)); rec(&pattern, &new_patterns, &mut memo);
println!("Memo: {:?}", memo_vec); }
let mut count = 0; let mut count = 0;
let mut count2 = 0; let mut count2 = 0;
for (i, line) in (&lines[2..]).iter().enumerate() { for (i, line) in (&lines[2..]).iter().enumerate() {
//println!("Line {} of {}", i, lines.len()-2); println!("Line {} of {}", i, lines.len()-2);
if let Some(c) = rec(&line, &new_patterns, &mut memo) { if let Some(c) = rec(&line, &new_patterns, &mut memo) {
count += 1; count += 1;
count2 += c; count2 += c;
@@ -59,17 +60,19 @@ fn solve(lines: Vec<String>) -> SResult<(usize, usize)> {
} }
let mut memo_vec: Vec<(&str, usize)> = memo.into_iter().collect(); let mut memo_vec: Vec<(&str, usize)> = memo.into_iter().collect();
memo_vec.sort_by(|a, b| a.0.cmp(&b.0)); memo_vec.sort_by(|a, b| a.0.cmp(&b.0));
println!("Memo: {:?}", memo_vec);
Ok((count, count2)) Ok((count, count2))
} }
fn rec<'a>(left: &'a str, patterns: &HashMap<char, Vec<(&'a str, HashSet<&'a str>)>>, memo: &mut HashMap<&'a str, usize>) -> Option<usize> { fn rec<'a>(
left: &'a str,
patterns: &Vec<(&'a str, HashSet<&'a str>)>,
memo: &mut HashMap<&'a str, usize>,
) -> Option<usize> {
if let Some(val) = memo.get(&left) { if let Some(val) = memo.get(&left) {
return Some(*val); return Some(*val);
} }
let mut count = 0; let mut count = 0;
let start = left.chars().next().unwrap(); for (pattern, large_patterns) in patterns {
for (pattern, large_patterns) in patterns.get(&start).unwrap_or(&vec!()) {
if let Some(substr) = left.strip_prefix(pattern) { if let Some(substr) = left.strip_prefix(pattern) {
if let Some(c) = rec(substr, patterns, memo) { if let Some(c) = rec(substr, patterns, memo) {
count += c; count += c;