AoC2021/src/day10.rs

146 lines
4.1 KiB
Rust

use std::str::FromStr;
use crate::Day;
pub struct Day10(Vec<Vec<BracketType>>, Vec<(usize, Bracket)>);
impl Day for Day10 {
fn init(content: String) -> anyhow::Result<Self> {
let l = content.lines().map(|x| x.chars().map(|x| x.to_string().parse().unwrap()).collect::<Vec<BracketType>>()).collect::<Vec<_>>();
Ok(Self(l.clone(), gather_part1(l)))
}
fn part1(&self) -> anyhow::Result<String> {
Ok(format!("{}", self.1.iter().map(|&(_, b)| {
match b {
Bracket::Round => 3,
Bracket::Square => 57,
Bracket::Curly => 1197,
Bracket::Angle => 25137,
}
}).sum::<u32>()))
}
fn part2(&self) -> anyhow::Result<String> {
let mut wrongs = self.1.clone();
let mut zz = self.0.clone();
wrongs.sort_unstable();
wrongs.iter().rev().for_each(|&(x, _)| std::mem::drop(zz.remove(x)));
let mut scores = Vec::new();
for z in zz {
let mut stack = Vec::new();
for bracket in z {
match bracket {
BracketType::Open(x) => stack.push(x),
BracketType::Close(x) => {
if let Some(y) = stack.pop() {
assert_eq!(y, x);
}
}
}
}
stack.reverse();
let mut score = 0_u64;
for b in stack {
score *= 5;
score += match b {
Bracket::Round => 1,
Bracket::Square => 2,
Bracket::Curly => 3,
Bracket::Angle => 4,
}
}
scores.push(score);
}
scores.sort_unstable();
Ok(format!("{:?}", scores[scores.len() / 2]))
}
}
fn gather_part1(v: Vec<Vec<BracketType>>) -> Vec<(usize, Bracket)> {
let mut wrongs = Vec::new();
for (idx, brackets) in v.iter().enumerate() {
let mut stack = Vec::new();
for &bracket in brackets {
match bracket {
BracketType::Open(x) => stack.push(x),
BracketType::Close(x) => {
if let Some(y) = stack.pop() {
if x != y {
wrongs.push((idx, x));
break;
}
}
}
}
}
}
wrongs
}
impl FromStr for BracketType {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"(" => Ok(BracketType::Open(Bracket::Round)),
"[" => Ok(BracketType::Open(Bracket::Square)),
"{" => Ok(BracketType::Open(Bracket::Curly)),
"<" => Ok(BracketType::Open(Bracket::Angle)),
")" => Ok(BracketType::Close(Bracket::Round)),
"]" => Ok(BracketType::Close(Bracket::Square)),
"}" => Ok(BracketType::Close(Bracket::Curly)),
">" => Ok(BracketType::Close(Bracket::Angle)),
_ => Err(()),
}
}
}
#[derive(Eq, PartialEq, Ord, PartialOrd, Copy, Clone, Debug)]
pub enum BracketType {
Open(Bracket),
Close(Bracket),
}
#[derive(Eq, PartialEq, Ord, PartialOrd, Copy, Clone, Debug)]
pub enum Bracket {
Round,
Square,
Curly,
Angle,
}
#[cfg(test)]
mod tests {
use crate::{Day, day_tests};
use crate::day10::Day10;
const INPUT: &str = r"[({(<(())[]>[[{[]{<()<>>
[(()[<>])]({[<{<<[]>>(
{([(<{}[<>[]}>{[]{[(<()>
(((({<>}<{<{<>}{[]{[]{}
[[<[([]))<([[{}[[()]]]
[{[{({}]{}}([{[{{{}}([]
{<[[]]>}<{[{[{[]{()[[[]
[<(<(<(<{}))><([]([]()
<{([([[(<>()){}]>(<<{{
<{([{{}}[<[[[<>{}]]]>[]]";
#[test]
fn part1_test() -> anyhow::Result<()> {
let d = Day10::init(INPUT.to_string())?;
assert_eq!("26397", d.part1()?);
Ok(())
}
#[test]
fn part2_test() -> anyhow::Result<()> {
let d = Day10::init(INPUT.to_string())?;
assert_eq!("288957", d.part2()?);
Ok(())
}
day_tests!(Day10, "10", "392421", "2769449099");
}