1
0
Fork 0
aoc2021/src/main.rs

96 lines
2.2 KiB
Rust
Raw Normal View History

2021-12-01 05:51:55 +00:00
#![feature(test)]
extern crate test;
2021-12-03 05:38:45 +00:00
const INPUTS: [&'static str; 2] = [
include_str!("../inputs/day3.sample.txt"),
include_str!("../inputs/day3.txt"),
];
2021-12-02 05:14:07 +00:00
2021-12-03 05:38:45 +00:00
fn cmds(input: &'static str) -> Vec<u64> {
input
.lines()
.filter(|&x| !x.is_empty())
.map(|x| u64::from_str_radix(x, 2).unwrap())
.collect()
2021-12-01 05:16:08 +00:00
}
2021-12-03 13:33:56 +00:00
fn solution<const MAX_LENGTH: usize>(levels: Vec<u64>) -> u64 {
let oxygen_gen_rating = filter_candidates::<MAX_LENGTH>(levels.clone(), true);
let co2_scrub_rating = filter_candidates::<MAX_LENGTH>(levels, false);
oxygen_gen_rating * co2_scrub_rating
}
fn filter_candidates<const MAX_LENGTH: usize>(mut levels: Vec<u64>, dominant: bool) -> u64 {
let mut i = 0;
while levels.len() > 1 {
let count = count_bits::<MAX_LENGTH>(&levels, dominant);
let leading = count & (1 << (MAX_LENGTH - i - 1));
levels = levels
.into_iter()
.filter(|&x| {
let pos = x & (1 << (MAX_LENGTH - i - 1));
return pos == leading;
})
.collect();
i += 1;
2021-12-03 05:38:45 +00:00
}
2021-12-02 05:14:07 +00:00
2021-12-03 13:33:56 +00:00
levels[0]
2021-12-02 05:18:04 +00:00
}
2021-12-03 13:33:56 +00:00
fn count_bits<const MAX_LENGTH: usize>(levels: &[u64], dominant: bool) -> u64 {
2021-12-03 05:38:45 +00:00
let n = levels.len();
2021-12-03 13:33:56 +00:00
let mut count = [0; MAX_LENGTH];
let mut mask = 0;
2021-12-03 05:38:45 +00:00
for &level in levels.iter() {
2021-12-03 13:33:56 +00:00
for i in 0..MAX_LENGTH {
let c = level & (1 << (MAX_LENGTH - i - 1));
2021-12-02 05:14:07 +00:00
2021-12-03 05:38:45 +00:00
if c != 0 {
count[i as usize] += 1;
2021-12-02 05:18:04 +00:00
}
2021-12-01 05:16:08 +00:00
}
}
2021-12-03 05:38:45 +00:00
for (i, c) in count.into_iter().enumerate() {
if c >= n - c {
2021-12-03 13:33:56 +00:00
mask |= 1 << (MAX_LENGTH - i - 1);
2021-12-03 05:38:45 +00:00
}
}
if dominant {
mask
} else {
!mask
}
2021-12-01 05:51:55 +00:00
}
fn main() {
2021-12-03 05:38:45 +00:00
let moves = cmds(INPUTS[0]);
2021-12-03 13:33:56 +00:00
let count = solution::<5>(moves);
2021-12-03 05:38:45 +00:00
println!("Result {}", count);
let moves = cmds(INPUTS[1]);
2021-12-03 13:33:56 +00:00
let count = solution::<12>(moves);
2021-12-03 05:38:45 +00:00
println!("Result {}", count);
2021-12-01 05:16:08 +00:00
}
2021-12-01 05:51:55 +00:00
#[bench]
fn solution_bench(b: &mut test::Bencher) {
2021-12-03 05:38:45 +00:00
let moves = cmds(INPUTS[1]);
2021-12-01 05:51:55 +00:00
b.iter(|| {
2021-12-03 13:33:56 +00:00
let v = solution::<12>(moves.clone());
2021-12-01 05:51:55 +00:00
test::black_box(v);
})
}
#[test]
fn solution_test() {
2021-12-03 13:33:56 +00:00
assert_eq!(solution::<5>(cmds(INPUTS[0])), 230);
assert_eq!(solution::<12>(cmds(INPUTS[1])), 4406844);
2021-12-01 05:51:55 +00:00
}