2021: day08: only store "hard" digits in mapping
This commit is contained in:
parent
b5c79e9b1c
commit
b5c4b72864
|
@ -65,21 +65,20 @@ impl<'a> Entry<'a> {
|
||||||
let mut mapping = Vec::new();
|
let mut mapping = Vec::new();
|
||||||
|
|
||||||
// first, let's get the easy digits
|
// first, let's get the easy digits
|
||||||
self.unique_signals
|
let easy_digits: Vec<(&str, u64)> = self
|
||||||
|
.unique_signals
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|signal| Self::translate_easy_digit(signal).zip(Some(signal)))
|
.filter_map(|signal| Some(*signal).zip(Self::translate_easy_digit(signal)))
|
||||||
.for_each(|(translation, &signal)| {
|
.collect();
|
||||||
mapping.push((signal, translation));
|
|
||||||
});
|
|
||||||
|
|
||||||
// now we can get `9` for free: it's the signal that uses 6 segments and has 4 in common
|
// now we can get `9` for free: it's the signal that uses 6 segments and has 4 in common
|
||||||
// with the digit `4` (`6` and `0` also use 6 segments, but only have 3 segments in common
|
// with the digit `4` (`6` and `0` also use 6 segments, but only have 3 segments in common
|
||||||
// with `4`).
|
// with `4`).
|
||||||
let (four, _) = *mapping
|
let (four, _) = *easy_digits
|
||||||
.iter()
|
.iter()
|
||||||
.find(|(_, translation)| *translation == 4)
|
.find(|(_, translation)| *translation == 4)
|
||||||
.context("no signal found for the digit 4!")?;
|
.context("no signal found for the digit 4!")?;
|
||||||
let nine = self
|
let nine = *self
|
||||||
.unique_signals
|
.unique_signals
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|signal| signal.len() == 6)
|
.filter(|signal| signal.len() == 6)
|
||||||
|
@ -88,32 +87,32 @@ impl<'a> Entry<'a> {
|
||||||
mapping.push((nine, 9));
|
mapping.push((nine, 9));
|
||||||
|
|
||||||
// `0` has 2 segments in common with `1`, while `6` only has 1.
|
// `0` has 2 segments in common with `1`, while `6` only has 1.
|
||||||
let (one, _) = *mapping
|
let (one, _) = *easy_digits
|
||||||
.iter()
|
.iter()
|
||||||
.find(|(_, translation)| *translation == 1)
|
.find(|(_, translation)| *translation == 1)
|
||||||
.context("no signal found for the digit 1!")?;
|
.context("no signal found for the digit 1!")?;
|
||||||
let zero = self
|
let zero = *self
|
||||||
.unique_signals
|
.unique_signals
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|signal| signal.len() == 6)
|
.filter(|&signal| signal.len() == 6)
|
||||||
.filter(|signal| *signal != nine)
|
.filter(|&signal| *signal != nine)
|
||||||
.find(|signal| one.chars().all(|c| signal.contains(c)))
|
.find(|signal| one.chars().all(|c| signal.contains(c)))
|
||||||
.context("couldn't identify any signal corresponding to the digit 0!")?;
|
.context("couldn't identify any signal corresponding to the digit 0!")?;
|
||||||
mapping.push((zero, 0));
|
mapping.push((zero, 0));
|
||||||
|
|
||||||
// `6` is an easy one now, the only other signal with 6 segments, that isn't nine or zero.
|
// `6` is an easy one now, the only other signal with 6 segments, that isn't nine or zero.
|
||||||
let six = self
|
let six = *self
|
||||||
.unique_signals
|
.unique_signals
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|signal| signal.len() == 6)
|
.filter(|signal| signal.len() == 6)
|
||||||
.find(|signal| *signal != nine && *signal != zero)
|
.find(|&signal| *signal != nine && *signal != zero)
|
||||||
.context("couldn't identify any signal corresponding to the digit 6!")?;
|
.context("couldn't identify any signal corresponding to the digit 6!")?;
|
||||||
mapping.push((six, 6));
|
mapping.push((six, 6));
|
||||||
|
|
||||||
// `2`, `3` and `5` have 5 segments each.
|
// `2`, `3` and `5` have 5 segments each.
|
||||||
//
|
//
|
||||||
// `3` has 2 segments in common with `1`.
|
// `3` has 2 segments in common with `1`.
|
||||||
let three = self
|
let three = *self
|
||||||
.unique_signals
|
.unique_signals
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|signal| signal.len() == 5)
|
.filter(|signal| signal.len() == 5)
|
||||||
|
@ -122,7 +121,7 @@ impl<'a> Entry<'a> {
|
||||||
mapping.push((three, 3));
|
mapping.push((three, 3));
|
||||||
|
|
||||||
// `5` has all its segments used in `6`, `2` doesn't.
|
// `5` has all its segments used in `6`, `2` doesn't.
|
||||||
let five = self
|
let five = *self
|
||||||
.unique_signals
|
.unique_signals
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|signal| signal.len() == 5)
|
.filter(|signal| signal.len() == 5)
|
||||||
|
@ -135,11 +134,11 @@ impl<'a> Entry<'a> {
|
||||||
.unique_signals
|
.unique_signals
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|signal| signal.len() == 5)
|
.filter(|signal| signal.len() == 5)
|
||||||
.find(|signal| *signal != five && *signal != three)
|
.find(|&signal| *signal != five && *signal != three)
|
||||||
.context("couldn't identify any signal corresponding to the digit 2!")?;
|
.context("couldn't identify any signal corresponding to the digit 2!")?;
|
||||||
mapping.push((two, 2));
|
mapping.push((two, 2));
|
||||||
|
|
||||||
debug_assert_eq!(mapping.len(), 10);
|
debug_assert_eq!(mapping.len(), 6);
|
||||||
|
|
||||||
Ok(mapping)
|
Ok(mapping)
|
||||||
}
|
}
|
||||||
|
@ -149,16 +148,21 @@ impl<'a> Entry<'a> {
|
||||||
for digit in &self.four_digits_output {
|
for digit in &self.four_digits_output {
|
||||||
// search is kind of ugly, but having to sort everything is probably time consuming as
|
// search is kind of ugly, but having to sort everything is probably time consuming as
|
||||||
// well.
|
// well.
|
||||||
let digit = digit_mapping
|
let digit = if let Some(translation) = Self::translate_easy_digit(digit) {
|
||||||
|
translation
|
||||||
|
} else {
|
||||||
|
*digit_mapping
|
||||||
.iter()
|
.iter()
|
||||||
.find_map(|(signal, translation)| {
|
.find_map(|(signal, translation)| {
|
||||||
if digit.len() == signal.len() && digit.chars().all(|c| signal.contains(c)) {
|
if digit.len() == signal.len() && digit.chars().all(|c| signal.contains(c))
|
||||||
|
{
|
||||||
Some(translation)
|
Some(translation)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.with_context(|| format!("couldn't translate digit `{}`", digit))?;
|
.with_context(|| format!("couldn't translate digit `{}`", digit))?
|
||||||
|
};
|
||||||
|
|
||||||
res = (res * 10) + digit;
|
res = (res * 10) + digit;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue