main.rs (2459B)
1 fn main() {
2 let input = std::fs::read_to_string("input.txt")
3 .unwrap()
4 .trim()
5 .split('\n')
6 .map(|s| s.to_string())
7 .collect::<Vec<_>>();
8 // 311895
9 println!("Part 1: {}", part_1(&input));
10 // 2904180541
11 println!("Part 2: {}", part_2(&input));
12 }
13
14 enum MatchResult {
15 Pair,
16 Stack,
17 Illegal(u64),
18 }
19
20 fn check_match(a: Option<&char>, b: char) -> MatchResult {
21 match (a, b) {
22 (Some('('), ')') | (Some('['), ']') | (Some('{'), '}') | (Some('<'), '>') => {
23 MatchResult::Pair
24 }
25 (None | Some('(' | '[' | '{' | '<'), '(' | '[' | '{' | '<') => MatchResult::Stack,
26 _ => MatchResult::Illegal(match b {
27 ')' => 3,
28 ']' => 57,
29 '}' => 1197,
30 '>' => 25137,
31 _ => unreachable!(),
32 }),
33 }
34 }
35
36 fn part_1(input: &Vec<String>) -> u64 {
37 let mut tot_score = 0;
38 for line in input {
39 let mut stack = std::collections::VecDeque::<char>::new();
40 for ch in line.chars() {
41 match check_match(stack.back(), ch) {
42 MatchResult::Pair => {
43 stack.pop_back();
44 }
45 MatchResult::Stack => {
46 stack.push_back(ch);
47 }
48 MatchResult::Illegal(score) => {
49 tot_score += score;
50 break;
51 }
52 }
53 }
54 }
55 tot_score
56 }
57
58 fn part_2(input: &Vec<String>) -> u64 {
59 let mut scores = Vec::<u64>::new();
60 'next_line: for line in input {
61 let mut stack = std::collections::VecDeque::<char>::new();
62 for ch in line.chars() {
63 match check_match(stack.back(), ch) {
64 MatchResult::Pair => {
65 stack.pop_back();
66 }
67 MatchResult::Stack => {
68 stack.push_back(ch);
69 }
70 MatchResult::Illegal(_) => {
71 continue 'next_line;
72 }
73 }
74 }
75 let mut score = 0;
76 for ch in stack.iter().rev() {
77 score = score * 5
78 + match ch {
79 '(' => 1,
80 '[' => 2,
81 '{' => 3,
82 '<' => 4,
83 _ => unreachable!(),
84 };
85 }
86 scores.push(score);
87 }
88 scores.sort();
89 scores[scores.len() / 2]
90 }