use std::error::Error; use std::fs::File; use std::io::{self, BufRead}; use std::vec::Vec; const WORD_LEN: usize = 12; fn to_weights(line: String) -> Vec { let mut result = zero_fill(WORD_LEN); for i in 0..WORD_LEN { result[i] = match line.chars().nth(i) { Some('1') => 1, Some('0') => -1, _ => panic!("Line to short"), }; } result } fn sum_weights(acc: Vec, weights: &Vec) -> Vec { acc.iter().zip(weights.iter()).map(|(a, b)| a + b).collect() } fn zero_fill(len: usize) -> Vec { let mut res = Vec::::new(); res.resize(len, 0); res } fn weights_to_int(weights: &Vec) -> i32 { let mut res = 0; for i in 0..weights.len() { if weights[i] > 0 { res |= 1 << WORD_LEN - 1 - i; } } res } fn main() -> Result<(), Box> { let file = File::open("inputs/day3.txt")?; let lines = io::BufReader::new(file).lines().map(|l| l.unwrap()); let weights: Vec> = lines.map(|l| to_weights(l)).collect(); let bits: Vec = weights.iter().fold(zero_fill(WORD_LEN), sum_weights); let mut gamma = 0; let mut epsilon = 0; for i in 0..bits.len() { if bits[i] > 0 { gamma |= 1 << WORD_LEN - 1 - i; } else { epsilon |= 1 << WORD_LEN - 1 - i; } } println!("Gamma: {}", gamma); println!("epsilon: {}", epsilon); println!("Answer1: {}", gamma * epsilon); let mut selection_pos = 0; let mut oxy_weights = weights.clone(); let mut oxy_bits = bits.clone(); while oxy_weights.len() > 1 { oxy_weights = oxy_weights .into_iter() .filter(|weights| { (weights[selection_pos] == 1 && oxy_bits[selection_pos] > 0) || (weights[selection_pos] == -1 && oxy_bits[selection_pos] < 0) || (weights[selection_pos] == 1 && oxy_bits[selection_pos] == 0) }) .collect(); selection_pos += 1; oxy_bits = oxy_weights.iter().fold(zero_fill(WORD_LEN), sum_weights); } println!("oxy_weights: {:?}", oxy_weights); selection_pos = 0; let mut co2_weights = weights.clone(); let mut co2_bits = bits.clone(); while co2_weights.len() > 1 { co2_weights = co2_weights .into_iter() .filter(|weights| { (weights[selection_pos] == -1 && co2_bits[selection_pos] > 0) || (weights[selection_pos] == 1 && co2_bits[selection_pos] < 0) || (weights[selection_pos] == -1 && co2_bits[selection_pos] == 0) }) .collect(); selection_pos += 1; co2_bits = co2_weights.iter().fold(zero_fill(WORD_LEN), sum_weights); } println!("co2_weights: {:?}", co2_weights); let oxy = weights_to_int(&oxy_weights[0]); let co2 = weights_to_int(&co2_weights[0]); println!("Answer2: {}", oxy * co2); Ok(()) }