mirror of
https://github.com/bertptrs/adventofcode.git
synced 2025-12-25 21:00:31 +01:00
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:
@@ -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()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user