Add (ugly) working day 3 in rust
This commit is contained in:
parent
b487214421
commit
d664a9efa8
7
d03/Cargo.lock
generated
Normal file
7
d03/Cargo.lock
generated
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "d03"
|
||||||
|
version = "0.1.0"
|
8
d03/Cargo.toml
Normal file
8
d03/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "d03"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
1000
d03/input.txt
Normal file
1000
d03/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
12
d03/input_short.txt
Normal file
12
d03/input_short.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
00100
|
||||||
|
11110
|
||||||
|
10110
|
||||||
|
10111
|
||||||
|
10101
|
||||||
|
01111
|
||||||
|
00111
|
||||||
|
11100
|
||||||
|
10000
|
||||||
|
11001
|
||||||
|
00010
|
||||||
|
01010
|
207
d03/src/main.rs
Normal file
207
d03/src/main.rs
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
use std::fs::File;
|
||||||
|
use std::io::{self, BufRead};
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
fn read_lines<P>(filename: P) -> io::Result<io::Lines<io::BufReader<File>>>
|
||||||
|
where
|
||||||
|
P: AsRef<Path>,
|
||||||
|
{
|
||||||
|
let file = File::open(filename)?;
|
||||||
|
Ok(io::BufReader::new(file).lines())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn str_to_bit_vec(binary_string: &str) -> Vec<u32> {
|
||||||
|
binary_string
|
||||||
|
.chars()
|
||||||
|
.map(|c| {
|
||||||
|
c.to_digit(2)
|
||||||
|
.expect(format!("Unknown binary string: {}", binary_string).as_str())
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MeanBits {
|
||||||
|
bits: Vec<u32>,
|
||||||
|
count: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn calc_gamma_epsilon(bit_mask: u32, values: Vec<Vec<u32>>) -> (u32, u32) {
|
||||||
|
let result = values
|
||||||
|
.iter()
|
||||||
|
.map(|bits| MeanBits {
|
||||||
|
bits: bits.clone(),
|
||||||
|
count: 1,
|
||||||
|
})
|
||||||
|
// Reduce by summing each bit and keeping count
|
||||||
|
.reduce(|acc, these_bits| MeanBits {
|
||||||
|
bits: acc
|
||||||
|
.bits
|
||||||
|
.iter()
|
||||||
|
.zip(these_bits.bits.iter())
|
||||||
|
.map(|val| val.0 + val.1)
|
||||||
|
.collect(),
|
||||||
|
count: acc.count + these_bits.count,
|
||||||
|
})
|
||||||
|
.expect(format!("No results!").as_str());
|
||||||
|
|
||||||
|
// Calc the gamma value from the MeanBits result
|
||||||
|
let gamma = result
|
||||||
|
.bits
|
||||||
|
.iter()
|
||||||
|
.map(|b| (b * 10) / result.count)
|
||||||
|
.map(|b| {
|
||||||
|
println!("digit {}, count {}", b, result.count);
|
||||||
|
b
|
||||||
|
})
|
||||||
|
.map(|b| match b {
|
||||||
|
b if b < 5 => "0".to_string(),
|
||||||
|
b if b >= 5 => "1".to_string(),
|
||||||
|
_ => panic!("not possible?"),
|
||||||
|
})
|
||||||
|
.reduce(|result, b| (&[result, b]).join(""))
|
||||||
|
.map(|gamma| {
|
||||||
|
println!("gamma {}", gamma);
|
||||||
|
gamma
|
||||||
|
})
|
||||||
|
.map(|gamma| u32::from_str_radix(gamma.as_str(), 2))
|
||||||
|
.expect("Could not parse gama value")
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// NOT the gamma and apply mask
|
||||||
|
let epsilon = !gamma & bit_mask;
|
||||||
|
|
||||||
|
(gamma, epsilon)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part1() -> (u32, u32) {
|
||||||
|
// Mask should be the length of a line
|
||||||
|
let bit_mask = u32::from_str_radix("111111111111", 2).unwrap();
|
||||||
|
let result = read_lines("input.txt")
|
||||||
|
.expect("Expected a file to read")
|
||||||
|
.map(|line| line.expect("Could not read line"))
|
||||||
|
.map(|line| str_to_bit_vec(&line))
|
||||||
|
// Prep for mean calc
|
||||||
|
.map(|bits| MeanBits {
|
||||||
|
bits: bits,
|
||||||
|
count: 1,
|
||||||
|
})
|
||||||
|
// Reduce by summing each bit and keeping count
|
||||||
|
.reduce(|acc, these_bits| MeanBits {
|
||||||
|
bits: acc
|
||||||
|
.bits
|
||||||
|
.iter()
|
||||||
|
.zip(these_bits.bits.iter())
|
||||||
|
.map(|val| val.0 + val.1)
|
||||||
|
.collect(),
|
||||||
|
count: acc.count + these_bits.count,
|
||||||
|
})
|
||||||
|
.expect(format!("No results!").as_str());
|
||||||
|
|
||||||
|
// Calc the gamma value from the MeanBits result
|
||||||
|
let gamma = result
|
||||||
|
.bits
|
||||||
|
.iter()
|
||||||
|
.map(|b| (b * 10) / result.count)
|
||||||
|
.map(|b| {
|
||||||
|
println!("digit {}, count {}", b, result.count);
|
||||||
|
b
|
||||||
|
})
|
||||||
|
.map(|b| match b {
|
||||||
|
b if b < 5 => "0".to_string(),
|
||||||
|
b if b >= 5 => "1".to_string(),
|
||||||
|
_ => panic!("not possible?"),
|
||||||
|
})
|
||||||
|
.reduce(|result, b| (&[result, b]).join(""))
|
||||||
|
.map(|gamma| {
|
||||||
|
println!("gamma {}", gamma);
|
||||||
|
gamma
|
||||||
|
})
|
||||||
|
.map(|gamma| u32::from_str_radix(gamma.as_str(), 2))
|
||||||
|
.expect("Could not parse gama value")
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// NOT the gamma and apply mask
|
||||||
|
let epsilon = !gamma & bit_mask;
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"Result for part 1: gamma: {} epsilon: {} result: {}",
|
||||||
|
gamma,
|
||||||
|
epsilon,
|
||||||
|
gamma * epsilon
|
||||||
|
);
|
||||||
|
|
||||||
|
(gamma, epsilon)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part2() {
|
||||||
|
// Oh wow... Getting uggly as my rust is not so great.
|
||||||
|
// This can almost certainly be done with less iterations, but I'm getting lazy now
|
||||||
|
let mask_length: u32 = 12;
|
||||||
|
let bit_mask =
|
||||||
|
u32::from_str_radix("1".repeat(mask_length.try_into().unwrap()).as_str(), 2).unwrap();
|
||||||
|
let bit_vects: Vec<Vec<u32>> = read_lines("input.txt")
|
||||||
|
.expect("Expected a file to read")
|
||||||
|
.map(|line| line.expect("Could not read line"))
|
||||||
|
.map(|line| str_to_bit_vec(&line))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let mut index: u32 = 0;
|
||||||
|
let mut oxy_vects = bit_vects.clone();
|
||||||
|
while oxy_vects.len() > 1 {
|
||||||
|
println!("Length of vectors is {}", oxy_vects.len());
|
||||||
|
let (gamma, _epsilon) = calc_gamma_epsilon(bit_mask, oxy_vects.clone());
|
||||||
|
let mask_bit: u32 = mask_length - index - 1;
|
||||||
|
let gamma_bit = gamma >> mask_bit & 1;
|
||||||
|
println!(
|
||||||
|
"Gamma is {:#b} and bit at index {} is {}",
|
||||||
|
gamma, mask_bit, gamma_bit
|
||||||
|
);
|
||||||
|
// let epsilon_bit = epsilon >> index & mask_bit;
|
||||||
|
let iu: usize = index.try_into().unwrap();
|
||||||
|
oxy_vects.retain(|bits| bits[iu] == gamma_bit);
|
||||||
|
index += 1;
|
||||||
|
}
|
||||||
|
let oxygen_rating = oxy_vects[0]
|
||||||
|
.iter()
|
||||||
|
.map(|b| b.to_string())
|
||||||
|
.reduce(|result, b| (&[result, b]).join(""))
|
||||||
|
.map(|oxy| u32::from_str_radix(oxy.as_str(), 2))
|
||||||
|
.expect("No oxygen rating")
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
index = 0;
|
||||||
|
let mut co2_vects = bit_vects.clone();
|
||||||
|
while co2_vects.len() > 1 {
|
||||||
|
println!("Length of vectors is {}", co2_vects.len());
|
||||||
|
let (_gamma, epsilon) = calc_gamma_epsilon(bit_mask, co2_vects.clone());
|
||||||
|
let mask_bit: u32 = mask_length - index - 1;
|
||||||
|
let epsilon_bit = epsilon >> mask_bit & 1;
|
||||||
|
println!(
|
||||||
|
"Gamma is {:#b} and bit at index {} is {}",
|
||||||
|
epsilon, mask_bit, epsilon_bit
|
||||||
|
);
|
||||||
|
// let epsilon_bit = epsilon >> index & mask_bit;
|
||||||
|
let iu: usize = index.try_into().unwrap();
|
||||||
|
co2_vects.retain(|bits| bits[iu] == epsilon_bit);
|
||||||
|
index += 1;
|
||||||
|
}
|
||||||
|
let co2_rating = co2_vects[0]
|
||||||
|
.iter()
|
||||||
|
.map(|b| b.to_string())
|
||||||
|
.reduce(|result, b| (&[result, b]).join(""))
|
||||||
|
.map(|oxy| u32::from_str_radix(oxy.as_str(), 2))
|
||||||
|
.expect("No oxygen rating")
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"Part 2! O2 = {}, CO2 = {}, Result is {}",
|
||||||
|
oxygen_rating,
|
||||||
|
co2_rating,
|
||||||
|
oxygen_rating * co2_rating
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
part1();
|
||||||
|
part2()
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user