2021: day03 part 1
This commit is contained in:
parent
43c89d10bf
commit
ee588b7ce7
1000
aoc2021/input/day03.txt
Normal file
1000
aoc2021/input/day03.txt
Normal file
File diff suppressed because it is too large
Load diff
12
aoc2021/input/day03_provided.txt
Normal file
12
aoc2021/input/day03_provided.txt
Normal file
|
@ -0,0 +1,12 @@
|
|||
00100
|
||||
11110
|
||||
10110
|
||||
10111
|
||||
10101
|
||||
01111
|
||||
00111
|
||||
11100
|
||||
10000
|
||||
11001
|
||||
00010
|
||||
01010
|
79
aoc2021/src/day03.rs
Normal file
79
aoc2021/src/day03.rs
Normal 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);
|
||||
}
|
||||
}
|
|
@ -2,3 +2,4 @@
|
|||
|
||||
pub mod day01;
|
||||
pub mod day02;
|
||||
pub mod day03;
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue