106 lines
3.0 KiB
Rust
106 lines
3.0 KiB
Rust
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<i32> {
|
|
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<i32>, weights: &Vec<i32>) -> Vec<i32> {
|
|
acc.iter().zip(weights.iter()).map(|(a, b)| a + b).collect()
|
|
}
|
|
|
|
fn zero_fill(len: usize) -> Vec<i32> {
|
|
let mut res = Vec::<i32>::new();
|
|
res.resize(len, 0);
|
|
res
|
|
}
|
|
|
|
fn weights_to_int(weights: &Vec<i32>) -> 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<dyn Error>> {
|
|
let file = File::open("inputs/day3.txt")?;
|
|
let lines = io::BufReader::new(file).lines().map(|l| l.unwrap());
|
|
|
|
let weights: Vec<Vec<i32>> = lines.map(|l| to_weights(l)).collect();
|
|
|
|
let bits: Vec<i32> = 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(())
|
|
}
|