implement day 3
This commit is contained in:
parent
8da65689bc
commit
4729fa062d
107
src/day_03.rs
Normal file
107
src/day_03.rs
Normal 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);
|
||||
}
|
||||
}
|
|
@ -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 }
|
||||
|
|
Loading…
Reference in a new issue