From a9e110ea968d738b9c93f3976cb5e98e5fb7a653 Mon Sep 17 00:00:00 2001 From: LongHairedHacker Date: Tue, 14 Dec 2021 15:26:23 +0100 Subject: [PATCH] Fast recusive version of day 14 --- src/bin/day14.rs | 98 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 71 insertions(+), 27 deletions(-) diff --git a/src/bin/day14.rs b/src/bin/day14.rs index c4fd87f..bc071fa 100644 --- a/src/bin/day14.rs +++ b/src/bin/day14.rs @@ -4,6 +4,72 @@ use std::fs::File; use std::io::{self, BufRead}; use std::vec::Vec; +fn recurse_pair( + a: char, + b: char, + depth: usize, + rules: &HashMap<(char, char), char>, + cache: &mut HashMap<(char, char, usize), HashMap>, +) -> HashMap { + if cache.contains_key(&(a, b, depth)) { + return cache[&(a, b, depth)].clone(); + } + + let middle = rules.get(&(a, b)).unwrap(); + + let mut res = HashMap::new(); + res.insert(*middle, 1); + + if depth == 1 { + return res; + } + + let res1 = recurse_pair(a, *middle, depth - 1, rules, cache); + let res2 = recurse_pair(*middle, b, depth - 1, rules, cache); + + for (c, count) in res1.iter() { + let count2 = res.get(c).unwrap_or_else(|| &0).clone(); + res.insert(*c, count + count2); + } + + for (c, count) in res2.iter() { + let count2 = res.get(c).unwrap_or_else(|| &0).clone(); + res.insert(*c, count + count2); + } + + cache.insert((a, b, depth), res.clone()); + + res +} + +fn compute_dist( + polymer_template: &Vec, + depth: usize, + rules: &HashMap<(char, char), char>, + cache: &mut HashMap<(char, char, usize), HashMap>, +) -> usize { + let mut dist: HashMap = HashMap::new(); + for c in polymer_template.iter() { + let count = dist.get(c).unwrap_or_else(|| &0).clone(); + dist.insert(*c, count + 1); + } + + for pair in polymer_template.windows(2) { + let res = recurse_pair(pair[0], pair[1], depth, &rules, cache); + for (c, count) in res.iter() { + let count2 = dist.get(c).unwrap_or_else(|| &0).clone(); + dist.insert(*c, count + count2); + } + } + + println!("{:?}", dist); + + let mut counts: Vec<&usize> = dist.values().collect(); + counts.sort(); + + *counts.last().unwrap() - *counts.first().unwrap() +} + fn main() -> Result<(), Box> { let file = File::open("inputs/day14.txt")?; let mut lines = io::BufReader::new(file).lines(); @@ -27,37 +93,15 @@ fn main() -> Result<(), Box> { ); } - for i in 0..40 { - let mut next_step: Vec = Vec::new(); - next_step.push(polymer_template[0]); - for pair in polymer_template.windows(2) { - //next_step.push(pair[0]); - if rules.contains_key(&(pair[0], pair[1])) { - next_step.push(rules[&(pair[0], pair[1])]); - } - next_step.push(pair[1]); - } + let mut cache: HashMap<(char, char, usize), HashMap> = HashMap::new(); - polymer_template = next_step; + let answer1 = compute_dist(&polymer_template, 10, &rules, &mut cache); - println!("{} : {}", i, polymer_template.len()); - } + println!("Answer1: {}", answer1); - let mut dist: HashMap = HashMap::new(); - for c in polymer_template.iter() { - let count = dist.get(c).unwrap_or_else(|| &0).clone(); - dist.insert(*c, count + 1); - } + let answer2 = compute_dist(&polymer_template, 40, &rules, &mut cache); - let mut counts: Vec<&usize> = dist.values().collect(); - counts.sort(); - - println!( - "Answer1: {}", - *counts.last().unwrap() - *counts.first().unwrap() - ); - - println!("Answer2: {}", 0); + println!("Answer2: {}", answer2); Ok(()) }