99 lines
3.0 KiB
Rust
99 lines
3.0 KiB
Rust
|
use std::collections::HashSet;
|
||
|
|
||
|
use itertools::Itertools;
|
||
|
|
||
|
pub fn day8() {
|
||
|
// let input = r#"
|
||
|
// be cfbegad cbdgef fgaecd cgeb fdcge agebfd fecdb fabcd edb | fdgacbe cefdb cefbgd gcbe
|
||
|
// edbfga begcd cbg gc gcadebf fbgde acbgfd abcde gfcbed gfec | fcgedb cgb dgebacf gc
|
||
|
// fgaebd cg bdaec gdafb agbcfd gdcbef bgcad gfac gcb cdgabef | cg cg fdcagb cbg
|
||
|
// fbegcd cbd adcefb dageb afcb bc aefdc ecdab fgdeca fcdbega | efabcd cedba gadfec cb
|
||
|
// aecbfdg fbg gf bafeg dbefa fcge gcbea fcaegb dgceab fcbdga | gecf egdcabf bgf bfgea
|
||
|
// fgeab ca afcebg bdacfeg cfaedg gcfdb baec bfadeg bafgc acf | gebdcfa ecba ca fadegcb
|
||
|
// dbcfg fgd bdegcaf fgec aegbdf ecdfab fbedc dacgb gdcebf gf | cefg dcbef fcge gbcadfe
|
||
|
// bdfegc cbegaf gecbf dfcage bdacg ed bedf ced adcbefg gebcd | ed bcgafe cdgba cbgef
|
||
|
// egadfb cdbfeg cegd fecab cgb gbdefca cg fgcdab egfdb bfceg | gbdfcae bgc cg cgb
|
||
|
// gcafb gcf dcaebfg ecagb gf abcdeg gaef cafbge fdbac fegbdc | fgae cfgab fg bagce
|
||
|
// "#;
|
||
|
let input = include_str!("../input/day8.txt");
|
||
|
|
||
|
let digits = input
|
||
|
.trim()
|
||
|
.lines()
|
||
|
.flat_map(|line| line.split("|").skip(1).next().unwrap().trim().split(" "));
|
||
|
|
||
|
println!(
|
||
|
"{}",
|
||
|
digits
|
||
|
.filter(|s| {
|
||
|
let len = s.len();
|
||
|
len == 2 || len == 4 || len == 3 || len == 7
|
||
|
})
|
||
|
.count()
|
||
|
);
|
||
|
|
||
|
let sum: usize = input.trim().lines().map(|l| note_value(l)).sum();
|
||
|
println!("{}", sum);
|
||
|
}
|
||
|
|
||
|
static T: bool = true;
|
||
|
static F: bool = false;
|
||
|
static DIGITS: [[bool; 7]; 10] = [
|
||
|
[T, T, T, F, T, T, T],
|
||
|
[F, F, T, F, F, T, F],
|
||
|
[T, F, T, T, T, F, T],
|
||
|
[T, F, T, T, F, T, T],
|
||
|
[F, T, T, T, F, T, F],
|
||
|
[T, T, F, T, F, T, T],
|
||
|
[T, T, F, T, T, T, T],
|
||
|
[T, F, T, F, F, T, F],
|
||
|
[T, T, T, T, T, T, T],
|
||
|
[T, T, T, T, F, T, T],
|
||
|
];
|
||
|
|
||
|
fn find_mapping(note: &str) -> Vec<char> {
|
||
|
let mut parts = note.split("|");
|
||
|
let unique_patterns = parts
|
||
|
.next()
|
||
|
.unwrap()
|
||
|
.trim()
|
||
|
.split(" ")
|
||
|
.collect::<HashSet<_>>();
|
||
|
|
||
|
assert!(unique_patterns.len() == 10);
|
||
|
|
||
|
let perm = "abcdefg".chars().permutations(7).find(|mapping| {
|
||
|
DIGITS.iter().all(|digit_pattern| {
|
||
|
unique_patterns
|
||
|
.iter()
|
||
|
.any(|p| &map_to_digit_pattern(p, mapping) == digit_pattern)
|
||
|
})
|
||
|
});
|
||
|
perm.unwrap()
|
||
|
}
|
||
|
|
||
|
fn map_to_digit_pattern(signal: &str, mapping: &[char]) -> [bool; 7] {
|
||
|
let mut result = [false; 7];
|
||
|
for c in signal.chars() {
|
||
|
let (pos, _) = mapping.iter().find_position(|&&map_c| map_c == c).unwrap();
|
||
|
result[pos] = true;
|
||
|
}
|
||
|
result
|
||
|
}
|
||
|
|
||
|
fn digit_for_pattern(pattern: &[bool; 7]) -> usize {
|
||
|
DIGITS.iter().find_position(|&p| p == pattern).unwrap().0
|
||
|
}
|
||
|
|
||
|
fn note_value(note: &str) -> usize {
|
||
|
let mapping = find_mapping(note);
|
||
|
note.split("|")
|
||
|
.skip(1)
|
||
|
.next()
|
||
|
.unwrap()
|
||
|
.trim()
|
||
|
.split(" ")
|
||
|
.map(|signal| digit_for_pattern(&map_to_digit_pattern(signal, &mapping)))
|
||
|
.fold(0, |acc, digit| acc * 10 + digit)
|
||
|
}
|