add: day19
This commit is contained in:
+30
-27
@@ -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();
|
||||||
let mut memo_vec: Vec<(&str, usize)> = memo.clone().into_iter().collect();
|
memo.insert("", 1);
|
||||||
memo_vec.sort_by(|a, b| a.0.cmp(&b.0));
|
|
||||||
println!("Memo: {:?}", memo_vec);
|
for pattern in &patterns {
|
||||||
|
rec(&pattern, &new_patterns, &mut memo);
|
||||||
|
}
|
||||||
|
|
||||||
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;
|
||||||
@@ -103,4 +106,4 @@ mod tests {
|
|||||||
let got = solve(strings).unwrap();
|
let got = solve(strings).unwrap();
|
||||||
assert_eq!(got, (6, 16));
|
assert_eq!(got, (6, 16));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user