implement day 3

This commit is contained in:
Jan Christian Grünhage 2021-12-04 11:47:22 +01:00
parent 8da65689bc
commit 4729fa062d
2 changed files with 108 additions and 0 deletions

107
src/day_03.rs Normal file
View file

@ -0,0 +1,107 @@
use aoc_runner_derive::{aoc, aoc_generator};
#[aoc_generator(day3)]
pub fn parse_diagnostics(input: &str) -> Vec<String> {
input.lines().map(String::from).collect()
}
#[aoc(day3, part1)]
pub fn calculate_power_consumption(input: &[String]) -> usize {
let gamma_factor = most_common_bit_string(input);
let epsilon_factor = invert_binary_string(&gamma_factor);
let gamma_factor = usize::from_str_radix(&gamma_factor, 2).unwrap();
let epsilon_factor = usize::from_str_radix(&epsilon_factor, 2).unwrap();
gamma_factor * epsilon_factor
}
pub fn most_common_bit(input: &[String], pos: usize) -> char {
let mut count = 0;
for val in input {
if val.get(pos..=pos).unwrap() == "1" {
count += 1
}
}
if count * 2 >= input.len() {
'1'
} else {
'0'
}
}
pub fn most_common_bit_string(input: &[String]) -> String {
let mut ret_val = String::new();
for i in 0..input[0].len() {
ret_val.push(most_common_bit(input, i))
}
ret_val
}
pub fn invert_binary_string(val: &str) -> String {
let mut ret_val = String::new();
for charactor in val.chars() {
match charactor {
'0' => ret_val.push('1'),
'1' => ret_val.push('0'),
_ => (),
}
}
ret_val
}
pub fn get_oxygen_generator_rating(input: &[String]) -> usize {
get_recursive_prefix_match(input, false)
}
pub fn get_co2_scrubber_rating(input: &[String]) -> usize {
get_recursive_prefix_match(input, true)
}
pub fn get_recursive_prefix_match(input: &[String], invert: bool) -> usize {
let mut input = Vec::from(input);
for i in 0..input[0].len() {
if input.len() > 1 {
let mut target = String::from(most_common_bit(&input, i));
if invert {
target = invert_binary_string(&target);
}
input.retain(|val| val.get(i..=i) == Some(&target));
} else {
break;
}
}
assert_eq!(input.len(), 1);
usize::from_str_radix(&input[0], 2).unwrap()
}
#[aoc(day3, part2)]
pub fn calculate_life_support_rating(input: &[String]) -> usize {
get_oxygen_generator_rating(input) * get_co2_scrubber_rating(input)
}
#[cfg(test)]
mod test {
const EXAMPLE_INPUT: &str = "00100
11110
10110
10111
10101
01111
00111
11100
10000
11001
00010
01010";
#[test]
fn test_power_consumption_example() {
let result = super::calculate_power_consumption(&super::parse_diagnostics(EXAMPLE_INPUT));
assert_eq!(result, 198);
}
#[test]
fn test_life_support_example() {
let result = super::calculate_life_support_rating(&super::parse_diagnostics(EXAMPLE_INPUT));
assert_eq!(result, 230);
}
}

View file

@ -2,5 +2,6 @@ use aoc_runner_derive::aoc_lib;
pub mod day_01;
pub mod day_02;
pub mod day_03;
aoc_lib! { year = 2021 }