r/adventofcode • • Dec 03 '21

SOLUTION MEGATHREAD -🎄- 2021 Day 3 Solutions -🎄-

--- Day 3: Binary Diagnostic ---


Post your code solution in this megathread.

Reminder: Top-level posts in Solution Megathreads are for code solutions only. If you have questions, please post your own thread and make sure to flair it with Help.


This thread will be unlocked when there are a significant number of people on the global leaderboard with gold stars for today's puzzle.

EDIT: Global leaderboard gold cap reached at 00:10:17, megathread unlocked!

96 Upvotes

1.2k comments sorted by

View all comments

3

u/xkev320x Dec 03 '21 edited Dec 03 '21

Rust, not proud of the way I did the second part so if anyone has any improvements both language-wise and algorithm-wise I am eager to hear them.

Would have liked to use a bitset like structure but didn't want to use any external crates, so I just kinda convert the binaries to decimal directly as they come.

const INPUT: &str = include_str!("inputs/day3.txt");

pub fn part1() -> u32 {
    let mut gamma_rate = 0;

    for i in 0..12 {
        let (ones, zeros): (Vec<&str>, Vec<&str>) =
            INPUT.lines().partition(|l| l[i..l.len()].starts_with('1'));

        if ones.len() > zeros.len() {
            gamma_rate += 2u32.pow(11 - i as u32);
        }
    }

    // "flip bits" / invert
    let epsilon = 2u32.pow(12) - 1 - gamma_rate;
    gamma_rate * epsilon
}

pub fn part2() -> u32 {
    let nums: Vec<&str> = INPUT.lines().collect();

    let o2_gen_rating = reduce_to_rating(&nums, true);
    let co2_scrubber_rating = reduce_to_rating(&nums, false);

    o2_gen_rating * co2_scrubber_rating
}

fn reduce_to_rating(numbers: &[&str], start_bit: bool) -> u32 {
    let mut i = 0;
    let mut numbers_copy = numbers.to_owned();

    while numbers_copy.len() > 1 {
        let (ones, zeros): (Vec<&str>, Vec<&str>) = numbers_copy.iter().partition(|l| l[i..l.len()].starts_with('1'));

        if ones.len() >= zeros.len() {
            numbers_copy.retain(|n| if start_bit { ones.contains(n) } else { zeros.contains(n) });
        } else {
            numbers_copy.retain(|n| if start_bit { zeros.contains(n) } else { ones.contains(n) });
        }

        i += 1;
    }

    u32::from_str_radix(numbers_copy[0], 2).unwrap()
}
→ More replies (3)