day3 completed

This commit is contained in:
JasterV 2021-12-07 23:14:17 +01:00
commit fe32a64958
3 changed files with 87 additions and 4 deletions

18
day3/Cargo.lock generated
View file

@ -5,3 +5,21 @@ version = 3
[[package]] [[package]]
name = "day3" name = "day3"
version = "0.1.0" version = "0.1.0"
dependencies = [
"itertools",
]
[[package]]
name = "either"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]]
name = "itertools"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3"
dependencies = [
"either",
]

View file

@ -6,3 +6,4 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
itertools = "0.10.3"

View file

@ -1,3 +1,5 @@
use itertools::FoldWhile::{Continue, Done};
use itertools::Itertools;
use std::{ use std::{
fs::File, fs::File,
io::{BufRead, BufReader, Lines, Result}, io::{BufRead, BufReader, Lines, Result},
@ -8,21 +10,83 @@ static INPUT_PATH: &str = "input.txt";
fn main() -> Result<()> { fn main() -> Result<()> {
let diagnostic_report = read_diagnostic_report(INPUT_PATH)?; let diagnostic_report = read_diagnostic_report(INPUT_PATH)?;
let [gamma_rate, epsilon_rate] = extract_report_rates(&diagnostic_report); let [gamma_rate, epsilon_rate, oxygen_rate, co2_rate] =
extract_report_rates(&diagnostic_report);
println!("First puzzle: {}", gamma_rate * epsilon_rate); println!("First puzzle: {}", gamma_rate * epsilon_rate);
println!("Second puzzle {}", oxygen_rate * co2_rate);
Ok(()) Ok(())
} }
fn extract_report_rates(report: &[String]) -> [i32; 2] { fn extract_report_rates(report: &[String]) -> [i32; 4] {
let sums = compute_digits_sums(report); let sums = compute_digits_sums(report);
let gamma_rate: String = map_sums(&sums, |&sum| if sum > 0 { "1" } else { "0" }).join(""); let gamma_rate = map_sums(&sums, |&sum| if sum > 0 { "1" } else { "0" }).join("");
let epsilon_rate: String = map_sums(&sums, |&sum| if sum > 0 { "0" } else { "1" }).join(""); let epsilon_rate = map_sums(&sums, |&sum| if sum > 0 { "0" } else { "1" }).join("");
let oxygen_rate = filter_report_while(
report,
|report, iteration| {
filter_report_by_nums_bit(report, iteration, |sum, c| {
sum >= 0 && c == '1' || sum < 0 && c == '0'
})
},
|report, iteration| report.len() == 1 || iteration > sums.len(),
)
.first()
.unwrap()
.clone();
let co2_rate = filter_report_while(
report,
|report, iteration| {
filter_report_by_nums_bit(report, iteration, |bit_sums, curr_bit| {
bit_sums >= 0 && curr_bit == '0' || bit_sums < 0 && curr_bit == '1'
})
},
|report, iteration| report.len() == 1 || iteration > sums.len(),
)
.first()
.unwrap()
.clone();
[ [
binary_str_to_int(&gamma_rate), binary_str_to_int(&gamma_rate),
binary_str_to_int(&epsilon_rate), binary_str_to_int(&epsilon_rate),
binary_str_to_int(&oxygen_rate),
binary_str_to_int(&co2_rate),
] ]
} }
fn filter_report_by_nums_bit<T>(report: Vec<String>, bit_index: usize, mut f: T) -> Vec<String>
where
T: FnMut(i32, char) -> bool,
{
let sum = compute_digits_sums(&report)[bit_index];
report
.into_iter()
.filter(|num| {
let c = get_char_at_index(num, bit_index);
f(sum, c)
})
.collect()
}
fn filter_report_while<T, H>(report: &[String], mut f: T, mut w: H) -> Vec<String>
where
T: FnMut(Vec<String>, usize) -> Vec<String>,
H: FnMut(&[String], usize) -> bool,
{
(0..)
.fold_while(Vec::from(report), |report, index| {
if w(&report, index) {
return Done(report);
}
Continue(f(report, index))
})
.into_inner()
}
fn get_char_at_index(word: &str, index: usize) -> char {
word[index..].chars().next().unwrap()
}
fn map_sums<T, F>(sums: &[i32], f: F) -> Vec<T> fn map_sums<T, F>(sums: &[i32], f: F) -> Vec<T>
where where
F: FnMut(&i32) -> T, F: FnMut(&i32) -> T,