AoC21/src/day08.rs

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)
}