port day 3 to bitvec

against my expectation, this performs worse
This commit is contained in:
Jan Christian Grünhage 2021-12-05 14:20:49 +01:00
parent ef64f62b28
commit 10e53e648d
3 changed files with 96 additions and 39 deletions

47
Cargo.lock generated
View File

@ -8,8 +8,10 @@ version = "0.1.0"
dependencies = [
"aoc-runner",
"aoc-runner-derive",
"bitvec",
"itertools",
"num",
"radix_fmt",
"yap",
]
@ -48,12 +50,30 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "bitvec"
version = "0.22.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5237f00a8c86130a0cc317830e558b966dd7850d48a953d998c813f01a41b527"
dependencies = [
"funty",
"radium",
"tap",
"wyz",
]
[[package]]
name = "either"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]]
name = "funty"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1847abb9cb65d566acd5942e94aea9c8f547ad02c98e1649326fc0e8910b8b1e"
[[package]]
name = "itertools"
version = "0.10.1"
@ -163,6 +183,18 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "radium"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "643f8f41a8ebc4c5dc4515c82bb8abd397b527fc20fd681b7c011c2aee5d44fb"
[[package]]
name = "radix_fmt"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce082a9940a7ace2ad4a8b7d0b1eac6aa378895f18be598230c5f2284ac05426"
[[package]]
name = "ryu"
version = "1.0.6"
@ -208,12 +240,27 @@ dependencies = [
"unicode-xid",
]
[[package]]
name = "tap"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
[[package]]
name = "unicode-xid"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]]
name = "wyz"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "129e027ad65ce1453680623c3fb5163cbf7107bfe1aa32257e7d0e63f9ced188"
dependencies = [
"tap",
]
[[package]]
name = "yap"
version = "0.7.1"

View File

@ -8,6 +8,8 @@ edition = "2021"
[dependencies]
aoc-runner = "0.3.0"
aoc-runner-derive = "0.3.0"
bitvec = "0.22.3"
itertools = "0.10.1"
num = "0.4.0"
radix_fmt = "1.0.0"
yap = "0.7.1"

View File

@ -1,80 +1,88 @@
use aoc_runner_derive::{aoc, aoc_generator};
use bitvec::prelude::*;
type Mbv = BitVec<Msb0>;
#[aoc_generator(day3)]
pub fn parse_diagnostics(input: &str) -> Vec<String> {
input.lines().map(String::from).collect()
pub fn parse_diagnostics(input: &str) -> Vec<Mbv> {
input
.lines()
.map(|line| {
let length = line.len();
let mut element = usize::from_str_radix(line, 2).unwrap();
element <<= usize::BITS - length as u32;
let mut vec: Mbv = Mbv::from_element(element);
vec.truncate(length);
vec
})
.collect()
}
#[aoc(day3, part1)]
pub fn calculate_power_consumption(input: &[String]) -> usize {
let gamma_factor = most_common_bit_string(input);
let epsilon_factor = invert_binary_string(&gamma_factor);
let gamma_factor = usize::from_str_radix(&gamma_factor, 2).unwrap();
let epsilon_factor = usize::from_str_radix(&epsilon_factor, 2).unwrap();
pub fn calculate_power_consumption(input: &[Mbv]) -> usize {
let gamma_factor = most_common_bit_vec(input);
let epsilon_factor = invert_bit_vec(&gamma_factor);
let gamma_factor = bit_vec_to_usize(&gamma_factor);
let epsilon_factor = bit_vec_to_usize(&epsilon_factor);
gamma_factor * epsilon_factor
}
pub fn most_common_bit(input: &[String], pos: usize) -> char {
let mut count = 0;
for val in input {
if val.get(pos..=pos).unwrap() == "1" {
count += 1
}
}
if count * 2 >= input.len() {
'1'
} else {
'0'
}
pub fn most_common_bit(input: &[Mbv], pos: usize) -> bool {
let count = input.iter().filter(|vec| *vec.get(pos).unwrap()).count();
count * 2 >= input.len()
}
pub fn most_common_bit_string(input: &[String]) -> String {
let mut ret_val = String::new();
pub fn most_common_bit_vec(input: &[Mbv]) -> Mbv {
let mut ret_val = Mbv::new();
for i in 0..input[0].len() {
ret_val.push(most_common_bit(input, i))
}
ret_val
}
pub fn invert_binary_string(val: &str) -> String {
let mut ret_val = String::new();
for charactor in val.chars() {
match charactor {
'0' => ret_val.push('1'),
'1' => ret_val.push('0'),
_ => (),
pub fn invert_bit_vec(val: &Mbv) -> Mbv {
val.iter().map(|val| !*val).collect()
}
pub fn bit_vec_to_usize(val: &Mbv) -> usize {
let mut ret_val = 0;
for bit in val {
ret_val <<= 1;
if *bit {
ret_val += 1;
}
}
ret_val
}
pub fn get_oxygen_generator_rating(input: &[String]) -> usize {
get_recursive_prefix_match(input, false)
pub fn get_oxygen_generator_rating(input: &[Mbv]) -> usize {
bit_vec_to_usize(&get_recursive_prefix_match(input, false))
}
pub fn get_co2_scrubber_rating(input: &[String]) -> usize {
get_recursive_prefix_match(input, true)
pub fn get_co2_scrubber_rating(input: &[Mbv]) -> usize {
bit_vec_to_usize(&get_recursive_prefix_match(input, true))
}
pub fn get_recursive_prefix_match(input: &[String], invert: bool) -> usize {
let mut input = Vec::from(input);
pub fn get_recursive_prefix_match(input: &[Mbv], invert: bool) -> Mbv {
let mut input: Vec<Mbv> = input.to_vec();
for i in 0..input[0].len() {
if input.len() > 1 {
let mut target = String::from(most_common_bit(&input, i));
let mut target = most_common_bit(&input, i);
if invert {
target = invert_binary_string(&target);
target = !target;
}
input.retain(|val| val.get(i..=i) == Some(&target));
input.retain(|val| val.get(i).unwrap() == target);
} else {
break;
}
}
assert_eq!(input.len(), 1);
usize::from_str_radix(&input[0], 2).unwrap()
input[0].clone()
}
#[aoc(day3, part2)]
pub fn calculate_life_support_rating(input: &[String]) -> usize {
pub fn calculate_life_support_rating(input: &[Mbv]) -> usize {
get_oxygen_generator_rating(input) * get_co2_scrubber_rating(input)
}