use std::fs; use std::path::Path; use std::collections::HashMap; use lazy_static::lazy_static; lazy_static! { static ref SCORE1: HashMap = { let mut m = HashMap::new(); m.insert(b')', 3); m.insert(b']', 57); m.insert(b'}', 1197); m.insert(b'>', 25137); m }; static ref SCORE2: HashMap = { let mut m = HashMap::new(); m.insert(b')', 1); m.insert(b']', 2); m.insert(b'}', 3); m.insert(b'>', 4); m }; } /* AOC21 Day 10: https://adventofcode.com/2021/day/10 */ fn main() { let input = Path::new("resources").join("input.txt"); let content = fs::read_to_string(input).expect("Unable to read input file"); ex1(&content); ex2(&content); } fn ex1(content: &str) { let ex1: u32 = content.lines() .filter_map(|l| check_line(l).err()) .sum(); println!("Ex1: the result is {}", ex1); } fn ex2(content: &str) { let mut ex2: Vec = content.lines() .filter_map(|l| check_line(l).ok()) .map(|v| v.iter().rev().fold(0, |a,p| a*5 + SCORE2.get(p).unwrap())) .collect(); ex2.sort(); println!("Ex2: the result is {}", ex2[ex2.len()/2]); } fn check_line(line: &str) -> Result,u32> { let acc = Ok(Vec::with_capacity(line.len())); line.bytes().fold(acc, |a,c| match a { Ok(mut a) => { match c { b'(' => { a.push(b')'); Ok(a) }, b'[' | b'{' | b'<' => { a.push(c+2); Ok(a) }, b')' | b']' | b'}' | b'>' => if a.pop().filter(|&x| x == c).is_some() { Ok(a) } else { Err(*SCORE1.get(&c).unwrap()) }, _ => unreachable!() } }, Err(_) => a }) }