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

pub fn run(input: String) {
    let scores_table = make_scores_table();
    let score = input.lines()
        .collect::<Vec<&str>>()
        .chunks(3).map(|group| {
            let init: Option<HashSet<char>> = None;
            let overlapping_chars: Vec<char> = group.into_iter().fold(init, |acc, group_member| {
                let group_member_charset: HashSet<char> = group_member.chars().collect();
                if let Some(acc) = acc {
                    let intersected: HashSet<char> = acc.intersection(&group_member_charset).map(|x| {x.clone()}).collect();
                    Some(intersected)
                } else {
                    Some(group_member_charset)
                }
            })
        .expect("didn't get any group members??!")
        .into_iter().collect();
        let ct = overlapping_chars.len();
        if ct != 1 {
            panic!("Couldn't find exactly one badge for group! found {}, {:?}", ct, group);
        }
        scores_table[&overlapping_chars[0]]
    }).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
}