summaryrefslogtreecommitdiff
path: root/2021/day10/src/main.rs
blob: 11f1f2ce588d20d26ea5569605cdcea9e05ba559 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
use std::fs;
use std::path::Path;
use std::collections::HashMap;
use lazy_static::lazy_static;

lazy_static! {
    static ref SCORE1: HashMap<u8,u32> = {
        let mut m = HashMap::new();
        m.insert(b')', 3);
        m.insert(b']', 57);
        m.insert(b'}', 1197);
        m.insert(b'>', 25137);
        m
    };
    static ref SCORE2: HashMap<u8,u64> = {
        let mut m = HashMap::new();
        m.insert(b')', 1);
        m.insert(b']', 2);
        m.insert(b'}', 3);
        m.insert(b'>', 4);
        m
    };
}

/* AOC21 Day 10: https://adventofcode.com/2021/day/10 */
fn main() {
    let input = Path::new("resources").join("input.txt");
    let content = fs::read_to_string(input).expect("Unable to read input file");
    ex1(&content);
    ex2(&content);
}

fn ex1(content: &str) {
    let ex1: u32 =
        content.lines()
               .filter_map(|l| check_line(l).err())
               .sum();
    println!("Ex1: the result is {}", ex1);
}

fn ex2(content: &str) {
    let mut ex2: Vec<u64> =
        content.lines()
               .filter_map(|l| check_line(l).ok())
               .map(|v| v.iter().rev().fold(0, |a,p| a*5 + SCORE2.get(p).unwrap()))
               .collect();
    ex2.sort();
    println!("Ex2: the result is {}", ex2[ex2.len()/2]);
}

fn check_line(line: &str) -> Result<Vec<u8>,u32> {
    let acc = Ok(Vec::with_capacity(line.len()));
    line.bytes().fold(acc, |a,c| match a {
        Ok(mut a) => {
            match c {
                b'(' => { a.push(b')'); Ok(a) },
                b'[' | b'{' | b'<' => { a.push(c+2); Ok(a) },
                b')' | b']' | b'}' | b'>' => 
                    if a.pop().filter(|&x| x == c).is_some() {
                        Ok(a)
                    } else {
                        Err(*SCORE1.get(&c).unwrap())
                    },
                _ => unreachable!()
            }
        },
        Err(_) => a
    })
}