-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path08.rs
120 lines (106 loc) · 2.98 KB
/
08.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#![feature(test)]
use rustc_hash::{FxHashMap, FxHashSet};
struct Line {
patterns: Vec<String>,
output: Vec<String>,
}
type Input = Vec<Line>;
fn setup(input: &str) -> Input {
input
.lines()
.map(|line| {
let mut line = line.trim().split(" | ");
let mut parse = || {
line.next()
.unwrap()
.split(' ')
.map(|x| x.to_string())
.collect()
};
Line {
patterns: parse(),
output: parse(),
}
})
.collect()
}
fn part1(input: &Input) -> String {
input
.iter()
.map(|line| {
line.output
.iter()
.filter(|x| [2, 3, 4, 7].contains(&x.len()))
.count()
})
.sum::<usize>()
.to_string()
}
fn parse_num(num: &str) -> u16 {
num.chars()
.map(|c| 1 << ((c as u16) - ('a' as u16)))
.sum::<u16>()
}
fn is_subset(mut a: u16, mut b: u16) -> bool {
while a > 0 {
if 1 & a & !b == 1 {
return false;
}
a >>= 1;
b >>= 1;
}
true
}
fn part2(input: &Input) -> String {
let digits = FxHashMap::from_iter([
((7, 2), 1),
((2, 5), 2),
((3, 5), 3),
((3, 4), 4),
((4, 5), 5),
((5, 3), 7),
((1, 7), 8),
]);
input
.iter()
.map(|line| {
let patterns: Vec<u16> = line.patterns.iter().map(|s| parse_num(s)).collect();
let output: Vec<u16> = line.output.iter().map(|s| parse_num(s)).collect();
let mut mp: FxHashMap<u16, u8> = FxHashMap::default();
let mut rp: FxHashMap<u8, u16> = FxHashMap::default();
let mut u: FxHashSet<u16> = FxHashSet::from_iter(patterns.iter().cloned());
for x in &patterns {
let sc = patterns.iter().filter(|y| is_subset(*x, **y)).count();
match digits.get(&(sc, x.count_ones())) {
None => {}
Some(digit) => {
mp.insert(*x, *digit);
rp.insert(*digit, *x);
u.remove(x);
}
}
}
let x = *u
.iter()
.find(|x| !is_subset(*rp.get(&5).unwrap(), **x))
.unwrap();
mp.insert(x, 0);
u.remove(&x);
let x = *u
.iter()
.find(|x| is_subset(*rp.get(&4).unwrap(), **x))
.unwrap();
mp.insert(x, 9);
u.remove(&x);
let x = *u.iter().next().unwrap();
mp.insert(x, 6);
output
.iter()
.map(|x| *mp.get(x).unwrap() as u32)
.reduce(|a, b| a * 10 + b)
.unwrap()
})
.sum::<u32>()
.to_string()
}
aoc::main!(2021, 8, ex: 1[b], 2);