DEV Community

Discussion on: Advent of Code 2020 Solution Megathread - Day 16: Ticket Translation

Collapse
 
benwtrent profile image
Benjamin Trent

My rust impl. Pretty gross use of "exactly one match" boolean thrashing. But, I was in a hurry and didn't want to mess with it any longer :)

#[derive(Hash, Eq, PartialEq)]
struct Field {
    name: String,
    range_1: (usize, usize),
    range_2: (usize, usize),
}

#[aoc(day16, part1)]
fn sum_invalid_tickets(input: &(Vec<Field>, Vec<usize>, Vec<Vec<usize>>)) -> usize {
    let mut sum = 0;
    for vec in &input.2 {
        for &v in vec {
            if input.0.iter().all(|f| f.is_invalid_number(&v)) {
                sum += v;
            }
        }
    }
    sum
}

#[aoc(day16, part2)]
fn departure_products(input: &(Vec<Field>, Vec<usize>, Vec<Vec<usize>>)) -> usize {
    let valid_tickets: Vec<&Vec<usize>> = input
        .2
        .iter()
        .filter(|&vec| {
            !vec.iter()
                .any(|v| input.0.iter().all(|f| f.is_invalid_number(&v)))
        })
        .collect();
    let mut field_translation = HashMap::new();
    let mut translated_fields = HashSet::new();
    while field_translation.len() < input.0.len() {
        for f in input.0.iter() {
            if translated_fields.contains(f) {
                continue;
            }
            let mut matched = false;
            let mut matched_more = false;
            let mut column = 0;
            for j in 0..input.0.len() {
                if field_translation.contains_key(&j) {
                    continue;
                }
                if !valid_tickets.iter().any(|vec| f.is_invalid_number(&vec[j])) {
                    if matched {
                        matched_more = true;
                        break;
                    }
                    matched = true;
                    column = j;
                }
            }
            if matched && !matched_more {
                field_translation.insert(column, f);
                translated_fields.insert(f);
            }
        }
    }

    input
        .1
        .iter()
        .enumerate()
        .filter(|(i, v)| field_translation[i].name.contains("departure"))
        .map(|(i, v)| v)
        .product()
}
Enter fullscreen mode Exit fullscreen mode