2021: day03 part 1

This commit is contained in:
Antoine Martin 2021-12-03 14:44:42 +01:00
parent 43c89d10bf
commit ee588b7ce7
5 changed files with 1094 additions and 1 deletions

1000
aoc2021/input/day03.txt Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,12 @@
00100
11110
10110
10111
10101
01111
00111
11100
10000
11001
00010
01010

79
aoc2021/src/day03.rs Normal file
View file

@ -0,0 +1,79 @@
use std::fmt::Write;
use anyhow::Result;
const INPUT: &str = include_str!("../input/day03.txt");
pub fn run() -> Result<String> {
let mut res = String::with_capacity(128);
writeln!(res, "part 1: {}", part1(INPUT)?)?;
Ok(res)
}
fn part1(input: &str) -> Result<u64> {
let binary_numbers: Vec<&str> = input.lines().collect();
// all binary numbers should have the same length
let size = binary_numbers[0].len();
let gamma = compute_gamma(&binary_numbers, size);
let epsilon = compute_epsilon(gamma, size);
Ok(gamma * epsilon)
}
fn compute_gamma(binary_numbers: &[&str], size: usize) -> u64 {
let mut gamma = 0;
for pos in 0..size {
let digit = if count_ones(binary_numbers, pos) > (binary_numbers.len() / 2) {
// majority of ones
1
} else {
// majority of zeroes
0
};
gamma = (gamma << 1) | digit;
}
gamma
}
fn count_ones(binary_numbers: &[&str], pos: usize) -> usize {
binary_numbers
.iter()
.filter(|&&num| num.chars().nth(pos).unwrap() == '1')
.count()
}
fn compute_epsilon(gamma: u64, size: usize) -> u64 {
// mask 0b000000000000000011111111 with `size` 1s.
let shift = u64::BITS - (size as u32);
let mask = (u64::MAX << shift) >> shift;
(!gamma) & mask
}
#[cfg(test)]
mod tests {
use super::*;
const PROVIDED: &str = include_str!("../input/day03_provided.txt");
#[test]
fn part1_provided() {
let binary_numbers: Vec<&str> = PROVIDED.lines().collect();
let size = binary_numbers[0].len();
let gamma = compute_gamma(&binary_numbers, size);
let epsilon = compute_epsilon(gamma, size);
assert_eq!(gamma, 22);
assert_eq!(epsilon, 9);
}
#[test]
fn part1_real() {
assert_eq!(part1(INPUT).unwrap(), 3429254);
}
}

View file

@ -2,3 +2,4 @@
pub mod day01;
pub mod day02;
pub mod day03;

View file

@ -4,9 +4,10 @@ use aoc::DayFunc;
use aoc2021::day01;
use aoc2021::day02;
use aoc2021::day03;
fn main() -> Result<()> {
let days: &[DayFunc] = &[day01::run, day02::run];
let days: &[DayFunc] = &[day01::run, day02::run, day03::run];
aoc::run(days)
}