Skip to content

Instantly share code, notes, and snippets.

@honnza
Created December 8, 2021 10:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save honnza/a507fddc7ff82079d9239f4eaf0fb7fd to your computer and use it in GitHub Desktop.
Save honnza/a507fddc7ff82079d9239f4eaf0fb7fd to your computer and use it in GitHub Desktop.
fn str_split_once<'a>(s: &'a str, pat: &str) -> Option<(&'a str, &'a str)> {
match s.split(pat).collect::<Vec<_>>()[..] {
[x, y] => Some((x, y)),
_ => None
}
}
fn day8(part: char, s: &str) -> String{
if part == 'a' {
s.lines().flat_map(|line| {
let (_, o) = str_split_once(line, " | ").unwrap();
o.split(" ").filter(|word| matches!(word.len(), 2 | 3 | 4 | 7))
}).count().to_string()
} else {
s.lines().map(|line| {
// we only need to identify enough segments to distinguish 2/3/5 an 0/6/9.
// For 2/3 we need E or F. For 3/5 we need B or C.
// Further we need two of C for 6, D for 0 or E for 9.
// C (top right) and E (bottom left) will suffice.
// C appears in 1 and in 8 digits total. E appears in 4 digits total.
let (i, o) = str_split_once(line, " | ").unwrap();
let dig_1 = i.split(" ").find(|word| word.len() == 2).unwrap();
let seg_c = ('a' ..= 'g').find(|&sc|
dig_1.contains(sc) && i.chars().filter(|&ic| ic == sc).count() == 8
).unwrap();
let seg_e = ('a' ..= 'g').find(|&sc|
i.chars().filter(|&ic| ic == sc).count() == 4
).unwrap();
o.split(" ").map(|word| match (word.len(), word.contains(seg_c), word.contains(seg_e)) {
(2, true, false) => 1, (3, true, false) => 7, (4, true, false) => 4,
(5, true, true) => 2, (5, true, false) => 3, (5, false, false) => 5,
(6, true, true) => 0, (6, false, true) => 6, (6, true, false) => 9,
(7, true, true) => 8, _ => panic!("{} | {}", i, word)
}).reduce(|a, d| 10 * a + d).unwrap()
}).sum::<usize>().to_string()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment