summaryrefslogtreecommitdiff
path: root/src/day3.rs
blob: 5c01b7a4acf3145cf248a1df923f18645a17396a (plain)
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
use std::{collections::{HashSet, HashMap}};

pub fn run(input: String) {
    if !input.is_ascii() {
        panic!("input wasn't ascii, character calculations won't work!");
    }

    let scores_table = make_scores_table();

    let ll: Vec<&str> = input.lines().collect();
    
    let score = ll.chunks(3).map(|gm| {
        let init: Option<HashSet<char>> = None;
        let lb: Vec<char> = gm.into_iter().fold(init, |maybe_acc, m| {
            let cs: HashSet<char> = m.chars().collect();
            if let Some(acc) = maybe_acc {
                let rr: HashSet<char> = acc.intersection(&cs).map(|x| {x.clone()}).collect();
                Some(rr)
            } else {
                Some(cs)
            }
        })
            .expect("didn't get any group members??!")
            .into_iter().collect();
        let ct = lb.len();
        if ct != 1 {
            panic!("Couldn't find exactly one badge for group! found {}, {:?}", ct, gm);
        }
        let ch = lb.into_iter().next().expect("foo");
        scores_table.get(&ch).expect(format!("couldn't find score for char {}", ch).as_str())
    }).sum::<u32>();
    println!("Day 3: {}", score);
}

fn make_scores_table() -> HashMap<char, u32> {
    let mut scores_table: HashMap<char,u32> = HashMap::new();
    let r1 = 'a'..='z';
    for (ix, ch) in r1.enumerate() {
        scores_table.insert(ch, (ix as u32)+1);
    }
    let r2 = 'A'..='Z';
    for (ix, ch) in r2.enumerate() {
        scores_table.insert(ch, (ix as u32)+27);
    }
    scores_table
}