From 584cad1690ec27b692c1701466826cff7ee6264f Mon Sep 17 00:00:00 2001 From: Joseph Montanaro Date: Thu, 16 Dec 2021 06:04:25 -0800 Subject: [PATCH] day 10 part 1 --- 2021/src/day10.rs | 108 ++++++++++++++++++++++++++++++++++++++++++++++ 2021/src/day9.rs | 7 --- 2021/src/lib.rs | 1 + 2021/src/main.rs | 6 +-- 4 files changed, 112 insertions(+), 10 deletions(-) create mode 100644 2021/src/day10.rs diff --git a/2021/src/day10.rs b/2021/src/day10.rs new file mode 100644 index 0000000..537ad7c --- /dev/null +++ b/2021/src/day10.rs @@ -0,0 +1,108 @@ +use color_eyre::eyre; +use eyre::eyre; + + +#[derive(Copy, Clone, PartialEq)] +enum BracketKind { + Paren, + Square, + Angle, + Curly, +} +use BracketKind::*; + + +#[derive(Copy, Clone, PartialEq)] +enum GroupDelimiter { + Start(BracketKind), + End(BracketKind), +} +use GroupDelimiter::*; + + +enum LineStatus { + Valid, + Incomplete(Vec), + Corrupted(usize), +} + + +fn score_corrupted(bk: BracketKind) -> usize { + match bk { + Paren => 3, + Square => 57, + Curly => 1197, + Angle => 25137, + } +} + + +fn score_incomplete(brackets: &[BracketKind]) -> usize { + let mut total = 0; + for bk in brackets.iter().rev() { + let additional = match bk { + Paren => 1, + Square => 2, + Curly => 3, + Angle => 4, + }; + total = total * 5 + additional; + } + total +} + + +fn parse_bracket(b: char) -> eyre::Result { + match b { + '(' => Ok(Start(Paren)), + ')' => Ok(End(Paren)), + '[' => Ok(Start(Square)), + ']' => Ok(End(Square)), + '<' => Ok(Start(Angle)), + '>' => Ok(End(Angle)), + '{' => Ok(Start(Curly)), + '}' => Ok(End(Curly)), + _ => Err(eyre!("Invalid value for bracket: {}", b)), + } +} + + +fn parse_line(line: &str) -> eyre::Result { + let mut state = Vec::new(); + for c in line.chars() { + match parse_bracket(c)? { + Start(current) => state.push(current), + End(current) => { + match state.last() { + Some(&prev) if prev == current => {state.pop();}, + _ => return Ok(LineStatus::Corrupted(score_corrupted(current))), + } + } + } + } + + if state.len() > 0 { + Ok(LineStatus::Incomplete(state)) + } + else { + Ok(LineStatus::Valid) + } +} + + +pub fn run(data: &str) -> eyre::Result<(usize, usize)> { + let mut total_corrupted = 0; + let mut completions = Vec::new(); + for line in data.lines() { + match parse_line(line)? { + LineStatus::Corrupted(s) => total_corrupted += s, + LineStatus::Incomplete(state) => completions.push(score_incomplete(&state)), + _ => (), + } + } + + completions.sort(); + let middle = completions.len() / 2 + 1; // given an odd length, this is the middle value + + Ok((total_corrupted, completions[middle])) +} diff --git a/2021/src/day9.rs b/2021/src/day9.rs index 025e74a..415cbdc 100644 --- a/2021/src/day9.rs +++ b/2021/src/day9.rs @@ -42,13 +42,6 @@ impl Iterator for NeighborsIter { } -// struct CellWindow { -// before: Option, -// cell: Cell, -// above: Option, -// } - - fn load(data: &str) -> eyre::Result> { let num_columns = data.lines().next().unwrap().len(); let mut heights = Vec2::new(num_columns); diff --git a/2021/src/lib.rs b/2021/src/lib.rs index 5deb0fc..a60f344 100644 --- a/2021/src/lib.rs +++ b/2021/src/lib.rs @@ -108,6 +108,7 @@ pub struct Vec2 { } +#[allow(dead_code)] impl Vec2 { pub fn new(columns: usize) -> Vec2 { Vec2 {data: Vec::::new(), columns} diff --git a/2021/src/main.rs b/2021/src/main.rs index ece7b77..824a2a4 100644 --- a/2021/src/main.rs +++ b/2021/src/main.rs @@ -4,14 +4,14 @@ use color_eyre::eyre; mod lib; use lib::load; -mod day9; +mod day10; fn main() -> eyre::Result<()> { - let data = load("data/09.txt")?; + let data = load("data/10.txt")?; let start = Instant::now(); - let (one, two) = day9::run(&data)?; + let (one, two) = day10::run(&data)?; let (dur, unit) = format_ns(start.elapsed().as_nanos()); let precision = 2.0 - dur.log10().floor();