use crate::prelude::*; pub fn solution() -> Solution { Solution::new(Day::new(10, 2021), part_1, part_2) .with_expected(387363, 4330777059_i64) } fn part_1(input: &str) -> Result { 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()) } fn part_2(input: &str) -> Result { 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()) }