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 day01;
|
||||||
pub mod day02;
|
pub mod day02;
|
||||||
|
pub mod day03;
|
||||||
|
|
|
@ -4,9 +4,10 @@ use aoc::DayFunc;
|
||||||
|
|
||||||
use aoc2021::day01;
|
use aoc2021::day01;
|
||||||
use aoc2021::day02;
|
use aoc2021::day02;
|
||||||
|
use aoc2021::day03;
|
||||||
|
|
||||||
fn main() -> Result<()> {
|
fn main() -> Result<()> {
|
||||||
let days: &[DayFunc] = &[day01::run, day02::run];
|
let days: &[DayFunc] = &[day01::run, day02::run, day03::run];
|
||||||
|
|
||||||
aoc::run(days)
|
aoc::run(days)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue