~nilium/aoc2021

1b19346d5bede84d090b5f674a388b10758c191c — Noel Cower 2 years ago aa8a844 main
day3: Implement part 2

Implement part 2 by doing repeated retain calls on the data. This could
be done better, but I don't really feel like doing that much more on
it.
1 files changed, 71 insertions(+), 4 deletions(-)

M day3/src/main.rs
M day3/src/main.rs => day3/src/main.rs +71 -4
@@ 1,5 1,6 @@
use anyhow::{anyhow, Result};
use anyhow::Result;
use std::io::{stdin, BufRead, BufReader};
use std::time::Instant;

fn main() -> Result<()> {
    let data: Vec<String> = {


@@ 33,6 34,8 @@ fn counts(data: &Vec<String>) -> Vec<usize> {
}

fn part1(data: &Vec<String>) {
    let now = Instant::now();

    let n = data.len();
    let cs = counts(data);
    let mut epsilon: u64 = 0;


@@ 48,10 51,74 @@ fn part1(data: &Vec<String>) {
        }
    }
    let mul = epsilon * gamma;

    let elapsed = now.elapsed();
    println!(
        "Part 1 => {} {:b} * {} {:b} = {}",
        epsilon, epsilon, gamma, gamma, mul
        "Part 1 [{}s {}us {}ns] => {} {:b} * {} {:b} = {}",
        elapsed.as_secs_f64(),
        elapsed.as_micros(),
        elapsed.as_nanos(),
        epsilon,
        epsilon,
        gamma,
        gamma,
        mul
    );
}

fn part2(data: &Vec<String>) {}
fn count_col(data: &Vec<String>, col: usize) -> usize {
    let mut n: usize = 0;
    for row in data.iter() {
        if row.as_bytes()[col] == b'1' {
            n += 1;
        }
    }
    n
}

fn part2(data: &Vec<String>) {
    let now = Instant::now();

    let columns = data[0].len();

    let mut oxygen = data.to_vec();
    let mut scrubber = data.to_vec();

    let keep = |i: usize, row: &String, c: u8| row.as_bytes()[i] == c;

    for col in 0..columns {
        let ones = count_col(&oxygen, col);
        let zeroes = oxygen.len() - ones;
        let find = if ones >= zeroes { b'1' } else { b'0' };
        oxygen.retain(|row| keep(col, row, find));
        if oxygen.len() == 1 {
            break;
        }
    }

    for col in 0..columns {
        let ones = count_col(&scrubber, col);
        let zeroes = scrubber.len() - ones;
        let find = if zeroes <= ones { b'0' } else { b'1' };
        scrubber.retain(|row| keep(col, row, find));
        if scrubber.len() == 1 {
            break;
        }
    }

    let oxygen_dec = u64::from_str_radix(oxygen[0].as_str(), 2).unwrap();
    let scrubber_dec = u64::from_str_radix(scrubber[0].as_str(), 2).unwrap();

    let elapsed = now.elapsed();
    println!(
        "Part 2 [{}s {}us {}ns] => {} {:?} * {} {:?} = {}",
        elapsed.as_secs_f64(),
        elapsed.as_micros(),
        elapsed.as_nanos(),
        oxygen_dec,
        oxygen[0],
        scrubber_dec,
        scrubber[0],
        oxygen_dec * scrubber_dec,
    );
}