Use bitsets for tracking what fits.

This commit is contained in:
2020-12-16 19:13:53 +01:00
parent 54d61e11f1
commit b934a268fe

View File

@@ -100,6 +100,8 @@ impl Solution for Day16 {
} }
} }
let mut can_fit: HashMap<&str, u64> = rules.keys().map(|k| (k.as_str(), 0)).collect();
while fixed_fields.len() != rules.len() { while fixed_fields.len() != rules.len() {
// Fix fields that are the only option for a certain spot // Fix fields that are the only option for a certain spot
for pos in 0..pos_can_be.len() { for pos in 0..pos_can_be.len() {
@@ -119,22 +121,22 @@ impl Solution for Day16 {
} }
} }
// Check if there are fields that only fit a single spot // Reset can_fit
let mut can_fit: HashMap<_, Vec<usize>> = HashMap::new(); can_fit.values_mut().for_each(|v| *v = 0);
for (pos, candiates) in pos_can_be.iter().enumerate() { for (pos, candiates) in pos_can_be.iter().enumerate() {
for candidate in candiates { for candidate in candiates {
can_fit.entry(candidate.clone()).or_default().push(pos); *can_fit.get_mut(candidate.as_str()).unwrap() |= 1 << pos;
} }
} }
for (field, pos) in can_fit.into_iter().filter(|(_, v)| v.len() == 1) { for (&field, &pos) in can_fit.iter().filter(|(_, v)| v.count_ones() == 1) {
let pos = pos[0]; let pos = pos.trailing_zeros() as usize;
assert!(!fixed_fields.contains_key(&field)); assert!(!fixed_fields.contains_key(field));
pos_can_be[pos].clear(); pos_can_be[pos].clear();
fixed_fields.insert(field, pos); fixed_fields.insert(field.to_owned(), pos);
} }
} }