advent-of-code

Perserverance, or the lack thereof

git clone git://git.shimmy1996.com/advent-of-code.git

main.rs (2861B)

    1 use std::collections::{HashMap, VecDeque};
    2 
    3 #[derive(Debug, Clone)]
    4 struct InsertionRules {
    5     rules: HashMap<(char, char), char>,
    6 }
    7 
    8 impl InsertionRules {
    9     fn new(s: &[String]) -> InsertionRules {
   10         let mut rules = HashMap::new();
   11         for line in s {
   12             let mut it = line.split(" -> ");
   13             let pair = it.next().unwrap().to_string();
   14             let mut pair_it = pair.chars();
   15             let left = pair_it.next().unwrap();
   16             let right = pair_it.next().unwrap();
   17             let insert = it.next().unwrap().chars().next().unwrap();
   18             rules.insert((left, right), insert);
   19         }
   20         Self { rules }
   21     }
   22 
   23     fn apply(&self, pairs: HashMap<(char, char), usize>) -> HashMap<(char, char), usize> {
   24         let mut new_pairs = HashMap::new();
   25         for ((a, b), count) in pairs {
   26             if let Some(&c) = self.rules.get(&(a, b)) {
   27                 new_pairs.insert((a, c), *new_pairs.get(&(a, c)).unwrap_or(&0) + count);
   28                 new_pairs.insert((c, b), *new_pairs.get(&(c, b)).unwrap_or(&0) + count);
   29             }
   30         }
   31         new_pairs
   32     }
   33 }
   34 
   35 fn main() {
   36     let input = std::fs::read_to_string("input.txt")
   37         .unwrap()
   38         .trim()
   39         .split('\n')
   40         .map(|s| s.to_string())
   41         .collect::<Vec<String>>();
   42     let template = input[0].chars().collect::<VecDeque<char>>();
   43     let rules = InsertionRules::new(&input[2..]);
   44     // 3697
   45     println!("Part 1: {}", part_1(&template, &rules, 10));
   46     // 4371307836157
   47     println!("Part 2: {}", part_1(&template, &rules, 40));
   48 }
   49 
   50 fn polymer_to_pairs(mut polymer: VecDeque<char>) -> HashMap<(char, char), usize> {
   51     let mut pairs = HashMap::new();
   52     let mut prev = None;
   53     loop {
   54         match (prev, polymer.pop_front()) {
   55             (None, Some(b)) => {
   56                 prev = Some(b);
   57             }
   58             (Some(a), Some(b)) => {
   59                 pairs.insert((a, b), *pairs.get(&(a, b)).unwrap_or(&0) + 1);
   60                 prev = Some(b);
   61             }
   62             _ => {
   63                 break;
   64             }
   65         }
   66     }
   67     pairs
   68 }
   69 
   70 fn part_1(template: &VecDeque<char>, rules: &InsertionRules, steps: usize) -> usize {
   71     let mut pairs = polymer_to_pairs(template.clone());
   72     for _ in 0..steps {
   73         pairs = rules.apply(pairs);
   74     }
   75 
   76     let mut counter = HashMap::<char, usize>::new();
   77     for ((a, b), count) in pairs {
   78         counter.insert(a, *counter.get(&a).unwrap_or(&0) + count);
   79         counter.insert(b, *counter.get(&b).unwrap_or(&0) + count);
   80     }
   81     let head = template.front().unwrap();
   82     let tail = template.back().unwrap();
   83     for (k, v) in counter.iter_mut() {
   84         if k == head || k == tail {
   85             *v = (*v + 1) / 2;
   86         } else {
   87             *v = *v / 2;
   88         }
   89     }
   90 
   91     *counter.values().max().unwrap() - *counter.values().min().unwrap()
   92 }