Less allocations in day 3 part 2

By working with binary numbers as integers rather than byte strings, we
don't need to allocate a Vec for each of them, reducing us to just the
allocations in the outer Vec.
This commit is contained in:
2021-12-04 11:13:54 +01:00
parent fb358be8f0
commit 392aefb32d

View File

@@ -42,44 +42,42 @@ pub fn part1(input: &mut dyn Read) -> String {
(gamma * epsilon).to_string() (gamma * epsilon).to_string()
} }
fn find_remaining(mut strings: Vec<Vec<u8>>, most: bool) -> u32 { fn find_remaining(mut strings: Vec<u32>, most: bool, len: usize) -> u32 {
let comp: fn(usize, usize) -> bool = if most { for pos in 1..=len {
|occurrences, len| occurrences * 2 >= len
} else {
|occurrences, len| occurrences * 2 < len
};
for pos in 0..strings[0].len() {
if strings.len() == 1 { if strings.len() == 1 {
break; break;
} }
let occurrences = strings.iter().filter(|b| b[pos] == b'1').count(); let bit = 1 << (len - pos);
let keep = if comp(occurrences, strings.len()) { let occurrences = strings.iter().filter(|&&b| (b & bit) == bit).count();
b'1'
let keep = if (occurrences * 2 < strings.len()) ^ most {
bit
} else { } else {
b'0' 0
}; };
strings.retain(|s| s[pos] == keep); strings.retain(|&b| (b & bit) == keep);
} }
strings[0] strings[0]
.iter()
.fold(0, |n, &b| (n << 1) | (b - b'0') as u32)
} }
pub fn part2(input: &mut dyn Read) -> String { pub fn part2(input: &mut dyn Read) -> String {
let mut strings = Vec::new(); let mut strings = Vec::new();
let mut reader = LineIter::new(input); let mut reader = LineIter::new(input);
let mut len = None;
while let Some(line) = reader.next() { while let Some(line) = reader.next() {
strings.push(line.as_bytes().to_owned()); strings.push(u32::from_str_radix(line, 2).unwrap());
len = Some(line.len());
} }
let oxygen = find_remaining(strings.clone(), true); let len = len.unwrap();
let co2 = find_remaining(strings, false);
let oxygen = find_remaining(strings.clone(), true, len);
let co2 = find_remaining(strings, false, len);
(oxygen * co2).to_string() (oxygen * co2).to_string()
} }