use crate::solvers::Solver; use memchr::{memchr, memchr_iter}; use std::io::BufRead; pub struct Laboratories {} impl Laboratories { const START_CHAR: u8 = b'S'; const SPLITTER_CHAR: u8 = b'^'; fn start_beam(line: &str) -> Vec { let mut beams = vec![0; line.len()]; if let Some(s) = memchr(Self::START_CHAR, line.as_bytes()) { beams[s] = 1; } beams } fn split_beams(line: &str, mut beams: Vec, mut splits: u64) -> (Vec, u64) { for s in memchr_iter(Self::SPLITTER_CHAR, line.as_bytes()) { if beams[s] > 0 { splits += 1; beams[s - 1] += beams[s]; beams[s + 1] += beams[s]; beams[s] = 0; } } (beams, splits) } } impl Solver for Laboratories { const PUZZLE_INDEX: u8 = 7; const PUZZLE_NAME: &'static str = "Laboratories"; fn process_data(&self, mut reader: R) -> (u64, u64) { let line = reader.by_ref().lines().next().unwrap().unwrap(); let mut beams = Self::start_beam(&line); let mut splits = 0; for line in reader.lines().map_while(Result::ok) { (beams, splits) = Self::split_beams(&line, beams, splits); } (splits, beams.iter().sum()) } }