day 3 part 2
this is horrible, thank you
This commit is contained in:
parent
0d245f117b
commit
af7f6179df
2 changed files with 109 additions and 0 deletions
|
@ -15,4 +15,8 @@ path = "src/day02/main.rs"
|
|||
name = "day03p1"
|
||||
path = "src/day03p1/main.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "day03p2"
|
||||
path = "src/day03p2/main.rs"
|
||||
|
||||
[dependencies]
|
||||
|
|
105
src/day03p2/main.rs
Normal file
105
src/day03p2/main.rs
Normal file
|
@ -0,0 +1,105 @@
|
|||
use std::io;
|
||||
|
||||
// there is no real reason to make this a struct i think
|
||||
struct SortedNums {
|
||||
zero: Vec<u32>,
|
||||
one: Vec<u32>,
|
||||
}
|
||||
|
||||
impl SortedNums {
|
||||
/// Sort all numbers in `v` by whether `bit` is a one or zero
|
||||
fn sort(v: &Vec<u32>, bit: usize) -> SortedNums {
|
||||
assert!(bit < 32);
|
||||
let mut zero = Vec::new();
|
||||
let mut one = Vec::new();
|
||||
|
||||
for num in v {
|
||||
if (*num & (1 << bit)) != 0 {
|
||||
one.push(*num);
|
||||
} else {
|
||||
zero.push(*num);
|
||||
}
|
||||
}
|
||||
|
||||
SortedNums {
|
||||
zero,
|
||||
one,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// i have a very strong suspicion this is in the standard library
|
||||
enum Pick {
|
||||
More,
|
||||
Less
|
||||
}
|
||||
|
||||
impl Pick {
|
||||
// also this should probably use references but the borrow
|
||||
// checker pissed me off way too hard for me to care
|
||||
pub fn pick<T>(&self, more: T, less: T) -> T {
|
||||
match self {
|
||||
Pick::More => more,
|
||||
Pick::Less => less,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn do_single_sort(nums: &Vec<u32>, bit: usize, which: Pick) -> Vec<u32> {
|
||||
let sn = SortedNums::sort(nums, bit);
|
||||
|
||||
if sn.one.len() < sn.zero.len() {
|
||||
which.pick(sn.zero, sn.one)
|
||||
} else {
|
||||
which.pick(sn.one, sn.zero)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let stdin = io::stdin();
|
||||
let mut num_bits = 0usize;
|
||||
let mut oxy_nums = Vec::new();
|
||||
let mut co2_nums = Vec::new();
|
||||
|
||||
// I don't really consider this part of the algorithm itself, it's just
|
||||
// obtaining the initial data. You could further optimize this by doing
|
||||
// the first sorting round directly in here, though.
|
||||
loop {
|
||||
let mut buf = String::new();
|
||||
match stdin.read_line(&mut buf).unwrap() {
|
||||
0 => break,
|
||||
_ => {
|
||||
let numstr = buf.trim();
|
||||
if num_bits == 0 {
|
||||
if numstr.len() > 32 {
|
||||
panic!("Only up to 32 bits supported");
|
||||
}
|
||||
num_bits = numstr.len();
|
||||
} else if numstr.len() != num_bits {
|
||||
panic!("Inconsistent number of bits");
|
||||
}
|
||||
|
||||
let input = u32::from_str_radix(numstr, 2).unwrap();
|
||||
oxy_nums.push(input);
|
||||
co2_nums.push(input);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if you wanted to get really fancy you could put co2
|
||||
// and oxygen into an array along with their Pick rule
|
||||
for bit in (0..num_bits).rev() {
|
||||
if oxy_nums.len() > 1 {
|
||||
oxy_nums = do_single_sort(&oxy_nums, bit, Pick::More);
|
||||
}
|
||||
if co2_nums.len() > 1 {
|
||||
co2_nums = do_single_sort(&co2_nums, bit, Pick::Less);
|
||||
}
|
||||
}
|
||||
|
||||
assert_eq!(oxy_nums.len(), 1);
|
||||
assert_eq!(co2_nums.len(), 1);
|
||||
println!("oxygen: {}", oxy_nums[0]);
|
||||
println!("co2: {}", co2_nums[0]);
|
||||
println!("answer: {}", oxy_nums[0] * co2_nums[0]);
|
||||
}
|
Loading…
Reference in a new issue