-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.rs
103 lines (96 loc) · 2.77 KB
/
main.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
use itertools::Itertools;
use rayon::iter::{ParallelBridge, ParallelIterator};
use std::collections::HashMap;
fn part1(input: &str) -> usize {
input
.lines()
.map(|line| {
let parts = line.split(" | ").collect::<Vec<_>>();
let digits = parts[1].split(' ').collect::<Vec<_>>();
digits
.iter()
.map(|digit| match digit.len() {
2 => 1,
3 => 1,
4 => 1,
7 => 1,
_ => 0,
})
.sum::<usize>()
})
.sum::<usize>()
}
fn decode(
signal: &str,
sig_seg_map: &HashMap<char, char>,
digit_map: &HashMap<String, usize>,
) -> Result<usize, ()> {
let trans = signal
.chars()
.map(|c| *sig_seg_map.get(&c).unwrap())
.sorted()
.collect::<String>();
if let Some(&digit) = digit_map.get(&trans) {
Ok(digit)
} else {
Err(())
}
}
fn decode_signals(input: &str, digit_map: &HashMap<String, usize>, chars: &Vec<char>) -> usize {
let parts = input.split(" | ").collect::<Vec<_>>();
let signals = parts[0].split(' ').collect::<Vec<_>>();
let digits = parts[1].split(' ').collect::<Vec<_>>();
let trans = chars
.iter()
.permutations(7)
.par_bridge()
.find_map_any(move |perm| {
let trans = perm
.iter()
.enumerate()
.map(|(i, &c)| (*c, chars[i]))
.collect::<HashMap<char, char>>();
if signals
.iter()
.all(|&signal| decode(signal, &trans, &digit_map).is_ok())
{
return Some(trans.clone());
}
None
})
.unwrap();
digits
.iter()
.map(|d| decode(d, &trans, &digit_map).unwrap())
.map(|d| format!("{}", d))
.collect::<String>()
.parse::<usize>()
.unwrap()
}
fn part2(input: &str) -> usize {
let digit_segments = vec![
"abcefg", "cf", "acdeg", "acdfg", "bcdf", "abdfg", "abdefg", "acf", "abcdefg", "abcdfg",
];
let digit_map = digit_segments
.iter()
.enumerate()
.map(|(i, s)| (String::from(s.clone()), i))
.collect::<HashMap<String, usize>>();
let chars = "abcdefg".chars().collect::<Vec<_>>();
input
.split('\n')
.map(|line| decode_signals(line, &digit_map, &chars))
.sum()
}
fn main() {
println!("Part 1: {:?}", part1(include_str!("in.txt")));
println!("Part 2: {:?}", part2(include_str!("in.txt")));
}
#[test]
fn test_part1() {
assert_eq!(part1(include_str!("test.txt")), 26);
}
#[test]
fn test_part2() {
assert_eq!(part2(include_str!("test.txt")), 61229);
}