Day 8 Refactoring I

Parsing and variable names
This commit is contained in:
kageru 2021-12-08 14:03:12 +01:00
parent 2ba51b2208
commit 0b77540d9d

View File

@ -9,8 +9,8 @@ use std::{array, lazy::Lazy, ops};
const DAY: usize = 08;
type Parsed<'a> = Vec<([&'a str; 10], [&'a str; 4])>;
const VALID_DISPLAYS: Lazy<[(&'static str, SSD); 10]> =
Lazy::new(|| ["abcefg", "cf", "acdeg", "acdfg", "bcdf", "abdfg", "abdefg", "acf", "abcdefg", "abcdfg"].map(|s| (s, SSD::from(s))));
const VALID_DISPLAYS: Lazy<[SSD; 10]> =
Lazy::new(|| ["abcefg", "cf", "acdeg", "acdfg", "bcdf", "abdfg", "abdefg", "acf", "abcdefg", "abcdfg"].map(SSD::from));
#[derive(Debug, PartialEq)]
struct SSD {
@ -82,7 +82,7 @@ fn parse_input(raw: &str) -> Parsed {
}
fn part1<'a>(parsed: &Parsed<'a>) -> usize {
parsed.iter().flat_map(|(_, output)| output).filter(|&&input| [2, 3, 4, 7].contains(&SSD::from(input).active_digits())).count()
parsed.iter().flat_map(|(_, output)| output).filter(|&&input| [2, 3, 4, 7].contains(&input.len())).count()
}
fn part2<'a>(parsed: &Parsed<'a>) -> usize {
@ -95,49 +95,41 @@ fn part2<'a>(parsed: &Parsed<'a>) -> usize {
let seven = input.iter().find(|d| d.active_digits() == 3).unwrap();
// We know the position of a for sure because it’s the only difference between 7 and 1
let a = (seven - one).to_array().iter().position(|&b| b).unwrap();
// And c and f are these two (both used in 1)
let c_or_f = one.to_array().iter().positions(|&b| b).collect_vec();
debug_assert_eq!(c_or_f.len(), 2);
// 4 uses b, c, d, f, but we already know c and f from 1, so this leaves b and d
let b_or_d = (four - one).to_array().iter().positions(|&b| b).collect_vec();
debug_assert_eq!(b_or_d.len(), 2);
// Now e and g have to be in the remaining two positions
let e_or_g = (0..7).filter(|n| ![a, b_or_d[0], b_or_d[1], c_or_f[0], c_or_f[1]].contains(n)).collect_vec();
debug_assert_eq!(e_or_g.len(), 2);
debug_assert_eq!(
[a, b_or_d[0], b_or_d[1], c_or_f[0], c_or_f[1], e_or_g[0], e_or_g[1]].into_iter().sorted().collect_vec(),
(0..7).collect_vec()
);
// And c and f are these two (both used in 1).
// Countrary to the name, these two values are both c_or_f,
// so we know c and f are these two, but we don’t know which is which.
let (c, f) = one.to_array().iter().positions(|&b| b).next_tuple().unwrap();
// 4 uses b, c, d, f, but we already know c and f from 1, so this leaves b and d.
let (b, d) = (four - one).to_array().iter().positions(|&b| b).next_tuple().unwrap();
// Now e and g have to be in the remaining two positions.
let (e, g) = (0..7).filter(|n| ![a, b, c, d, f].contains(n)).next_tuple().unwrap();
debug_assert_eq!([a, b, c, d, e, f, g].into_iter().sorted().collect_vec(), (0..7).collect_vec());
// Now there are 8 possible combinations from multiplying the 3 x_or_y we constructed above.
let mapping = iproduct!(
[&b_or_d, &b_or_d.iter().copied().rev().collect()],
[&c_or_f, &c_or_f.iter().copied().rev().collect()],
[&e_or_g, &e_or_g.iter().copied().rev().collect()]
)
.map(|(b_d, c_f, e_g)| {
let mut m = [' '; 7];
m[a] = 'a';
m[b_d[0]] = 'b';
m[c_f[0]] = 'c';
m[b_d[1]] = 'd';
m[e_g[0]] = 'e';
m[c_f[1]] = 'f';
m[e_g[1]] = 'g';
Mapping(m)
})
.find(|m| {
raw_input.iter().all(|i| {
let translated: String = i.chars().map(|n| m.translate(n)).collect();
let ssd = SSD::from(translated.as_ref());
VALID_DISPLAYS.iter().any(|(_, d)| d == &ssd)
let mapping = iproduct!([[b, d], [d, b]], [[c, f], [f, c]], [[e, g], [g, e]])
.map(|([b, d], [c, f], [e, g])| {
let mut m = [' '; 7];
m[a] = 'a';
m[b] = 'b';
m[c] = 'c';
m[d] = 'd';
m[e] = 'e';
m[f] = 'f';
m[g] = 'g';
Mapping(m)
})
})
.unwrap();
.find(|m| {
raw_input.iter().all(|i| {
let translated: String = i.chars().map(|n| m.translate(n)).collect();
let ssd = SSD::from(translated.as_ref());
VALID_DISPLAYS.iter().any(|d| d == &ssd)
})
})
.unwrap();
raw_output
.iter()
.map(|i| i.chars().map(|n| mapping.translate(n)).collect::<String>())
.map(|t| SSD::from(t.as_ref()))
.map(|ssd| VALID_DISPLAYS.iter().position(|(_, d)| &ssd == d).unwrap())
.map(|ssd| VALID_DISPLAYS.iter().position(|d| &ssd == d).unwrap())
.fold(0, |acc, n| (acc + n) * 10)
/ 10
})