main.rs (3555B)
1 fn main() {
2 let input = std::fs::read_to_string("input.txt")
3 .unwrap()
4 .trim()
5 .split('\n')
6 .map(|x| {
7 let parsed = x
8 .split(" | ")
9 .map(|y| {
10 y.split_whitespace()
11 .map(|x| x.to_string())
12 .collect::<Vec<String>>()
13 })
14 .collect::<Vec<_>>();
15 (parsed[0].clone(), parsed[1].clone())
16 })
17 .collect::<Vec<_>>();
18 // 284
19 println!("Part 1: {}", part_1(&input));
20 // 973499
21 println!("Part 2: {}", part_2(&input));
22 }
23
24 fn part_1(input: &Vec<(Vec<String>, Vec<String>)>) -> usize {
25 let mut simple_digit_count = 0;
26 for (_, output) in input {
27 for digit in output {
28 match digit.len() {
29 // 1, 4, 7, 8
30 2 | 4 | 3 | 7 => simple_digit_count += 1,
31 _ => (),
32 }
33 }
34 }
35 simple_digit_count
36 }
37
38 fn overlap(a: &str, b: &str) -> usize {
39 a.chars().map(|c| b.contains(c) as usize).sum()
40 }
41
42 fn part_2(input: &Vec<(Vec<String>, Vec<String>)>) -> i32 {
43 let mut output_sum = 0;
44 for (patterns, output) in input {
45 let mut mapping = std::collections::HashMap::<String, i32>::new();
46 let mut mapping_rev = std::collections::HashMap::<i32, String>::new();
47 // easy digits
48 for pattern in patterns {
49 match pattern.len() {
50 2 => {
51 mapping.insert(pattern.to_string(), 1);
52 mapping_rev.insert(1, pattern.to_string());
53 }
54 4 => {
55 mapping.insert(pattern.to_string(), 4);
56 mapping_rev.insert(4, pattern.to_string());
57 }
58 3 => {
59 mapping.insert(pattern.to_string(), 7);
60 mapping_rev.insert(7, pattern.to_string());
61 }
62 7 => {
63 mapping.insert(pattern.to_string(), 8);
64 mapping_rev.insert(8, pattern.to_string());
65 }
66 _ => (),
67 }
68 }
69 // decode hard digits as overlaps with easy digits
70 for pattern in patterns {
71 match (
72 pattern.len(),
73 overlap(pattern, &mapping_rev[&1]),
74 overlap(pattern, &mapping_rev[&4]),
75 ) {
76 (6, 2, 3) => {
77 mapping.insert(pattern.to_string(), 0);
78 }
79 (5, 1, 2) => {
80 mapping.insert(pattern.to_string(), 2);
81 }
82 (5, 2, 3) => {
83 mapping.insert(pattern.to_string(), 3);
84 }
85 (5, 1, 3) => {
86 mapping.insert(pattern.to_string(), 5);
87 }
88 (6, 1, 3) => {
89 mapping.insert(pattern.to_string(), 6);
90 }
91 (6, 2, 4) => {
92 mapping.insert(pattern.to_string(), 9);
93 }
94 (2 | 4 | 3 | 7, _, _) => (),
95 other => {
96 println!("Unexpected pattern: {:?}", other);
97 }
98 }
99 }
100 output_sum += output.iter().fold(0, |acc, x| {
101 let val = mapping
102 .iter()
103 .find(|(k, _)| k.len() == x.len() && overlap(k, x) == x.len())
104 .unwrap()
105 .1;
106 acc * 10 + val
107 });
108 }
109 output_sum
110 }