93 lines
1.9 KiB
Rust
93 lines
1.9 KiB
Rust
//! Day 10 of 2021.
|
|
|
|
use crate::prelude::*;
|
|
|
|
/// Get the solution for day 10 of 2021.
|
|
pub fn solution() -> Solution {
|
|
Solution::new(Day::new(10, 2021), part_1, part_2)
|
|
.with_expected(387363, 4330777059_i64)
|
|
}
|
|
|
|
/// The logic to solve part one.
|
|
fn part_1(input: &str) -> Result<String> {
|
|
let mut syntax_error_score = 0;
|
|
|
|
for line in input.lines() {
|
|
let mut tokens = VecDeque::new();
|
|
|
|
for token in line.chars() {
|
|
if ['(', '[', '{', '<'].contains(&token) {
|
|
tokens.push_back(token);
|
|
continue;
|
|
}
|
|
|
|
let expected_close = match tokens.pop_back() {
|
|
Some('(') => ')',
|
|
Some('[') => ']',
|
|
Some('{') => '}',
|
|
Some('<') => '>',
|
|
_ => unreachable!(),
|
|
};
|
|
|
|
if token != expected_close {
|
|
syntax_error_score += match token {
|
|
')' => 3,
|
|
']' => 57,
|
|
'}' => 1197,
|
|
'>' => 25137,
|
|
_ => unreachable!(),
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
Ok(syntax_error_score.to_string())
|
|
}
|
|
|
|
/// The logic to solve part two.
|
|
fn part_2(input: &str) -> Result<String> {
|
|
let mut scores = vec![];
|
|
|
|
'line_loop: for line in input.lines() {
|
|
let mut line_score: isize = 0;
|
|
let mut tokens = VecDeque::new();
|
|
|
|
for token in line.chars() {
|
|
if ['(', '[', '{', '<'].contains(&token) {
|
|
tokens.push_back(token);
|
|
continue;
|
|
}
|
|
|
|
let expected_close = match tokens.pop_back() {
|
|
Some('(') => ')',
|
|
Some('[') => ']',
|
|
Some('{') => '}',
|
|
Some('<') => '>',
|
|
_ => unreachable!(),
|
|
};
|
|
|
|
if token != expected_close {
|
|
continue 'line_loop;
|
|
}
|
|
}
|
|
|
|
for token in tokens.into_iter().rev() {
|
|
let token_score = match token {
|
|
'(' => 1,
|
|
'[' => 2,
|
|
'{' => 3,
|
|
'<' => 4,
|
|
_ => unreachable!(),
|
|
};
|
|
|
|
line_score *= 5;
|
|
line_score += token_score;
|
|
}
|
|
|
|
scores.push(line_score);
|
|
}
|
|
|
|
scores.sort();
|
|
Ok(scores[scores.len() / 2].to_string())
|
|
}
|