92 lines
1.9 KiB
Rust
92 lines
1.9 KiB
Rust
use std::collections::VecDeque;
|
|
|
|
use color_eyre::Result;
|
|
|
|
pub fn solve() -> Result<()> {
|
|
let input_data = include_str!("../../data/day_10.txt").trim();
|
|
println!("Day 10 Part 1: {}", part_1(input_data)?);
|
|
println!("Day 10 Part 2: {}", part_2(input_data)?);
|
|
Ok(())
|
|
}
|
|
|
|
fn part_1(input: &str) -> Result<usize> {
|
|
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)
|
|
}
|
|
|
|
fn part_2(input: &str) -> Result<isize> {
|
|
let mut scores = vec![];
|
|
|
|
'line_loop: for line in input.lines() {
|
|
let mut line_score = 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_by(|a, b| a.cmp(b));
|
|
Ok(scores[scores.len() / 2])
|
|
}
|