aoc2021-rust

Advent of Code 2021 Solutions in Rust
git clone https://git.sinitax.com/sinitax/aoc2021-rust
Log | Files | Refs | README | sfeed.txt

main.rs (2731B)


      1#[macro_use]
      2extern crate lazy_static;
      3
      4use std::collections::HashMap;
      5use bimap::BiMap;
      6
      7lazy_static! {
      8    static ref COMPLETION_POINTS: HashMap<char, usize> = {
      9        let mut m = HashMap::new();
     10        m.insert(')', 1);
     11        m.insert(']', 2);
     12        m.insert('}', 3);
     13        m.insert('>', 4);
     14        m
     15    };
     16    static ref CORRUPTION_POINTS: HashMap<char, usize> = {
     17        let mut m = HashMap::new();
     18        m.insert(')', 3);
     19        m.insert(']', 57);
     20        m.insert('}', 1197);
     21        m.insert('>', 25137);
     22        m
     23    };
     24    static ref MATCH: BiMap<char, char> = {
     25        let mut m = BiMap::new();
     26        m.insert('(', ')');
     27        m.insert('[', ']');
     28        m.insert('{', '}');
     29        m.insert('<', '>');
     30        m
     31    };
     32}
     33
     34const OPENING: [char; 4] = ['(', '[', '{', '<'];
     35const CLOSING: [char; 4] = [')', ']', '}', '>'];
     36
     37fn part1(aoc: &mut aoc::Info) {
     38    let mut score: usize = 0;
     39    for line in aoc.input.lines() {
     40        let mut stack: Vec<char> = Vec::new();
     41        for c in line.chars() {
     42            if OPENING.contains(&c) {
     43                stack.push(c);
     44            } else {
     45                assert!(CLOSING.contains(&c));
     46                let first = stack.pop();
     47                if first == None || MATCH.get_by_right(&c).unwrap() != &first.unwrap() {
     48                    score += CORRUPTION_POINTS.get(&c).unwrap();
     49                    break;
     50                }
     51            }
     52        }
     53        /* ignore incomplete for now */
     54    }
     55
     56    aoc.answer = Some(format!("{}", score));
     57    aoc.solution = Some("167379");
     58}
     59
     60fn part2(aoc: &mut aoc::Info) {
     61    let mut scores: Vec<usize> = Vec::new();
     62    for line in aoc.input.lines() {
     63        let mut stack: Vec<char> = Vec::new();
     64
     65        let mut corrupt = false;
     66        for c in line.chars() {
     67            if OPENING.contains(&c) {
     68                stack.push(c);
     69            } else {
     70                assert!(CLOSING.contains(&c));
     71                let first = stack.pop();
     72                if first == None || MATCH.get_by_right(&c).unwrap() != &first.unwrap() {
     73                    corrupt = true;
     74                    break;
     75                }
     76            }
     77        }
     78
     79        if corrupt == false && stack.len() > 0 { /* incomplete */
     80            let mut score: usize = 0;
     81            while stack.len() > 0 {
     82                let c = stack.pop().unwrap();
     83                score *= 5;
     84                score += COMPLETION_POINTS.get(MATCH.get_by_left(&c).unwrap()).unwrap();
     85            }
     86            scores.push(score);
     87        }
     88    }
     89    assert!(scores.len() % 2 == 1);
     90
     91    scores.sort();
     92
     93    aoc.answer = Some(format!("{}", scores[scores.len() / 2]));
     94    aoc.solution = Some("2776842859");
     95}
     96
     97fn main() {
     98    aoc::run(part1, part2);
     99}