DEV Community

Discussion on: AoC Day 2: Inventory Management System

Collapse
 
shritesh profile image
Shritesh Bhattarai • Edited

Rust
Part 1

use std::collections::HashMap;

fn contains_repeats(input: &str) -> (bool, bool) {
    let mut count = HashMap::new();

    input.chars().for_each(|c| {
        let n = count.entry(c).or_insert(0);
        *n += 1;
    });

    let two = count.iter().any(|(_, &v)| v == 2);
    let three = count.iter().any(|(_, &v)| v == 3);

    (two, three)
}

pub fn checksum(input: &[&str]) -> usize {
    let (twos, threes): (Vec<_>, Vec<_>) = input.iter().map(|&s| contains_repeats(s)).unzip();
    let two = twos.iter().filter(|&x| *x).count();
    let three = threes.iter().filter(|&x| *x).count();

    two * three
}

Part 2
I'm still searching for a nice iterator adapter to replace the nested loop. I finally used the itertools crate and it's AMAZING!!!

use itertools::Itertools;

fn hamming(input1: &str, input2: &str) -> usize {
    input1
        .chars()
        .zip(input2.chars())
        .filter(|(a, b)| a != b)
        .count()
}

fn common(input1: &str, input2: &str) -> String {
    input1
        .chars()
        .zip(input2.chars())
        .filter_map(|(a, b)| match a == b {
            true => Some(a),
            false => None,
        })
        .collect()
}

pub fn find_common(input: &[&str]) -> String {
    input
        .iter()
        .tuple_combinations()
        .find_map(|(first, second)| match hamming(first, second) {
            1 => Some(common(first, second)),
            _ => None,
        })
        .unwrap()
}