From 120d53c0ff20574866ce10fa0538fb8b0dd2ef82 Mon Sep 17 00:00:00 2001 From: Federico Igne Date: Thu, 23 Jun 2022 19:06:22 +0100 Subject: Reorganize repository structure --- 2021/day3/src/main.rs | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 2021/day3/src/main.rs (limited to '2021/day3/src/main.rs') diff --git a/2021/day3/src/main.rs b/2021/day3/src/main.rs new file mode 100644 index 0000000..d943de0 --- /dev/null +++ b/2021/day3/src/main.rs @@ -0,0 +1,65 @@ +use std::fs; +use std::path::Path; + +const ENTRY_LENGTH: usize = 12; + +/* AOC21 Day 3: https://adventofcode.com/2021/day/3 */ +fn main() { + let input = Path::new("resources").join("input.txt"); + let content = fs::read_to_string(input).expect("Unable to read input file"); + let report: Vec = content.lines().map(|l| u32::from_str_radix(l,2).expect("Malformed input")).collect(); + ex1(&report); + ex2(report); +} + +fn ex1(report: &[u32]) { + let gamma = compute_gamma(&report); + let epsilon = compute_epsilon(gamma); + println!("Ex1: the result is {} ({} * {})", gamma*epsilon, gamma, epsilon); +} + +fn compute_gamma(report: &[u32]) -> u32 { + let length = report.len() as u32; + let mut counter: Vec = vec![0; ENTRY_LENGTH]; + report.iter().for_each(|entry| counter.iter_mut().enumerate().for_each(|(i,v)| *v += (entry >> i) & 1)); + counter.iter().enumerate().map(|(i,v)| if v*2 > length { 1 << i } else { 0 }).sum() +} + +fn compute_epsilon(gamma: u32) -> u32 { + gamma ^ ((1 << ENTRY_LENGTH)-1) +} + +fn ex2(report: Vec) { + let o2 = compute_rating(report.clone(), ENTRY_LENGTH, 1); + let co2 = compute_rating(report, ENTRY_LENGTH, 0); + println!("Ex2: the result is {} ({} * {})", o2*co2, o2, co2); +} + +fn compute_rating(mut ratings: Vec, bit: usize, criterion: u32) -> u32 { + if ratings.len() == 1 || bit == 0 { + ratings[0] + } else { + let ones = ratings.iter().filter(|&r| ((r >> bit-1) & 1) == 1).count(); + let sel = if 2*ones < ratings.len() { 1^criterion } else { criterion }; + ratings.retain(|&r| ((r >> bit-1) & 1) == sel); + compute_rating(ratings, bit-1, criterion) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + const TEST_INPUT: [u32;12] = [0b00100, 0b11110, 0b10110, 0b10111, 0b10101, 0b01111, 0b00111, 0b11100, 0b10000, 0b11001, 0b00010, 0b01010]; + const ENTRY_LENGTH: usize = 5; + + #[test] + fn oxygen_generator_rating() { + assert_eq!(23,compute_rating(Vec::from(TEST_INPUT), ENTRY_LENGTH, 1)) + } + + #[test] + fn co2_scrubber_rating() { + assert_eq!(10,compute_rating(Vec::from(TEST_INPUT), ENTRY_LENGTH, 0)) + } +} -- cgit v1.2.3