day 10 part 1

This commit is contained in:
Joseph Montanaro 2021-12-16 06:04:25 -08:00
parent bf72a26b2b
commit 584cad1690
4 changed files with 112 additions and 10 deletions

108
2021/src/day10.rs Normal file
View File

@ -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<BracketKind>),
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<GroupDelimiter> {
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<LineStatus> {
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]))
}

View File

@ -42,13 +42,6 @@ impl Iterator for NeighborsIter {
} }
// struct CellWindow {
// before: Option<Cell>,
// cell: Cell,
// above: Option<Cell>,
// }
fn load(data: &str) -> eyre::Result<Vec2<Cell>> { fn load(data: &str) -> eyre::Result<Vec2<Cell>> {
let num_columns = data.lines().next().unwrap().len(); let num_columns = data.lines().next().unwrap().len();
let mut heights = Vec2::new(num_columns); let mut heights = Vec2::new(num_columns);

View File

@ -108,6 +108,7 @@ pub struct Vec2<T> {
} }
#[allow(dead_code)]
impl<T> Vec2<T> { impl<T> Vec2<T> {
pub fn new(columns: usize) -> Vec2<T> { pub fn new(columns: usize) -> Vec2<T> {
Vec2 {data: Vec::<T>::new(), columns} Vec2 {data: Vec::<T>::new(), columns}

View File

@ -4,14 +4,14 @@ use color_eyre::eyre;
mod lib; mod lib;
use lib::load; use lib::load;
mod day9; mod day10;
fn main() -> eyre::Result<()> { fn main() -> eyre::Result<()> {
let data = load("data/09.txt")?; let data = load("data/10.txt")?;
let start = Instant::now(); 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 (dur, unit) = format_ns(start.elapsed().as_nanos());
let precision = 2.0 - dur.log10().floor(); let precision = 2.0 - dur.log10().floor();