Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
epidemian
GitHub Repository: epidemian/advent-of-code-2021
Path: blob/main/src/day08.rs
97 views
1
pub fn run() {
2
let entries: Vec<Entry> = include_str!("inputs/day08")
3
.lines()
4
.map(parse_entry)
5
.collect();
6
7
let easy_digits_count: usize = entries.iter().map(count_easy_digits).sum();
8
println!("{}", easy_digits_count);
9
10
let output_sum: usize = entries.iter().map(decode_output).sum();
11
println!("{}", output_sum)
12
}
13
14
struct Entry<'a> {
15
signals: Vec<&'a str>,
16
output: Vec<&'a str>,
17
}
18
19
fn parse_entry(s: &str) -> Entry {
20
let (signals, output) = s.split_once(" | ").unwrap();
21
Entry {
22
signals: signals.split(" ").collect(),
23
output: output.split(" ").collect(),
24
}
25
}
26
27
fn count_easy_digits(entry: &Entry) -> usize {
28
entry
29
.output
30
.iter()
31
.filter(|digit| [2, 3, 4, 7].contains(&digit.len()))
32
.count()
33
}
34
35
fn decode_output(Entry { signals, output }: &Entry) -> usize {
36
let one_signal = *signals.iter().find(|s| s.len() == 2).unwrap();
37
let four_signal = *signals.iter().find(|s| s.len() == 4).unwrap();
38
let output_digits: Vec<usize> = output
39
.iter()
40
.map(|&s| {
41
let overlap_with_one = s.chars().filter(|ch| one_signal.contains(*ch)).count();
42
let overlap_with_four = s.chars().filter(|ch| four_signal.contains(*ch)).count();
43
match s.len() {
44
2 => 1,
45
3 => 7,
46
4 => 4,
47
5 => {
48
// 2, 3 and 5 have 5 segments
49
if overlap_with_one == 2 {
50
3
51
} else if overlap_with_four == 3 {
52
5
53
} else {
54
2
55
}
56
}
57
6 => {
58
// 0, 6 and 9 have 6 segments
59
if overlap_with_four == 4 {
60
9
61
} else if overlap_with_one == 2 {
62
0
63
} else {
64
6
65
}
66
}
67
7 => 8,
68
_ => unreachable!(),
69
}
70
})
71
.collect();
72
output_digits.iter().fold(0, |a, b| a * 10 + b)
73
}
74
75