From 50eb0465143e12db12778c23ddc8db78572fce0c Mon Sep 17 00:00:00 2001 From: Thomas Ruoff Date: Fri, 31 Dec 2021 01:22:46 +0100 Subject: [PATCH] task 2 day03 - feels still noob'y --- day03/data/sample | 12 ++++++++ day03/src/main.rs | 76 ++++++++++++++++++++++++++++++++++++----------- 2 files changed, 70 insertions(+), 18 deletions(-) create mode 100644 day03/data/sample diff --git a/day03/data/sample b/day03/data/sample new file mode 100644 index 0000000..a6366a8 --- /dev/null +++ b/day03/data/sample @@ -0,0 +1,12 @@ +00100 +11110 +10110 +10111 +10101 +01111 +00111 +11100 +10000 +11001 +00010 +01010 diff --git a/day03/src/main.rs b/day03/src/main.rs index 718d1c7..8084c05 100644 --- a/day03/src/main.rs +++ b/day03/src/main.rs @@ -8,13 +8,61 @@ fn main() { task1(&data); - task2(&data); + task2(&data); } fn task2(data: &Vec>) { - let a = filter_by_first_bit_n(data, true, 0); + println!("oxygen generator rating"); + let oxygen_generator_rating = get_rating(data, 0, true); + println!("co2 scrubber"); + let co2_scrubber_rating = get_rating(data, 0, false); + println!("live support rating {:?}", to_dec(&co2_scrubber_rating) * to_dec(&oxygen_generator_rating)); +} - println!("{:?}", a); +fn get_rating(data: &Vec>, index: usize, oxygen_flag: bool) -> Vec { + let filter_value = most_common_at_index(data, index, oxygen_flag); + println!("filter value {:?}", filter_value); + let result: Vec> = data + .iter() + .filter(|v| v[index] == filter_value) + .cloned() + .collect(); + + if index > data[0].len() { + panic!("index out of bounds for first vector") + } + + if result.len() == 1 { + return result[0].clone(); + } + + return get_rating(&result, index + 1, oxygen_flag); +} + +fn most_common_at_index(data: &Vec>, index: usize, oxygen_flag: bool) -> bool { + let half = data.len() as f32 / 2 as f32; + let true_count = data.into_iter().fold(0, |accum, item| { + if *item.get(index).unwrap() { + accum + 1 + } else { + accum + } + }); + return if oxygen_flag { true_count as f32 >= half} else {half > true_count as f32}; +} + +fn to_dec(measurement: &Vec) -> u32 { + return measurement + .into_iter() + .enumerate() + .fold(0, |accum, (pos, item)| { + let exp: u32 = (MAX_BITS - pos - 1) as u32; + if *item { + accum + (2 as u32).pow(exp) + } else { + accum + } + }); } fn task1(data: &Vec>) { @@ -33,21 +81,12 @@ fn task1(data: &Vec>) { println!("power consumption {}", epsilon * gamma); } -fn filter_by_first_bit_n(data: &Vec>, value: bool, n: usize) -> Vec { - let result: Vec> = data.iter().filter(|v| v[n] == value).cloned().collect(); - - if result.len() == 1 { - return result[0].clone(); - } - - return filter_by_first_bit_n(&result, value, n+1); -} - fn parse(data: &String) -> Vec> { let mut result: Vec> = vec![]; for line in data.lines() { - let thing: Vec = line.chars() - .map(|v| if v == '1' { return true } else { return false }) + let thing: Vec = line + .chars() + .map(|v| if v == '1' { return true } else { return false }) .collect(); result.push(thing); @@ -57,13 +96,14 @@ fn parse(data: &String) -> Vec> { } fn count(data: &Vec>, value: bool) -> Vec { - let mut result = vec![0 ; data[0].len()]; + let mut result = vec![0; data[0].len()]; for item in data.iter() { for (pos, v) in item.iter().enumerate() { - if *v == value { result[pos] += 1 } + if *v == value { + result[pos] += 1 + } } } return result; } -