From b934a268fec07f1eb12d518f5f12e40b92ee3881 Mon Sep 17 00:00:00 2001 From: Bert Peters Date: Wed, 16 Dec 2020 19:13:53 +0100 Subject: [PATCH] Use bitsets for tracking what fits. --- 2020/src/day16.rs | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/2020/src/day16.rs b/2020/src/day16.rs index d07888f..ad4d357 100644 --- a/2020/src/day16.rs +++ b/2020/src/day16.rs @@ -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() { // Fix fields that are the only option for a certain spot 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 - let mut can_fit: HashMap<_, Vec> = HashMap::new(); + // Reset can_fit + can_fit.values_mut().for_each(|v| *v = 0); for (pos, candiates) in pos_can_be.iter().enumerate() { 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) { - let pos = pos[0]; - assert!(!fixed_fields.contains_key(&field)); + for (&field, &pos) in can_fit.iter().filter(|(_, v)| v.count_ones() == 1) { + let pos = pos.trailing_zeros() as usize; + assert!(!fixed_fields.contains_key(field)); pos_can_be[pos].clear(); - fixed_fields.insert(field, pos); + fixed_fields.insert(field.to_owned(), pos); } }