use std::convert::TryFrom; use std::str::FromStr; use anyhow::Result; struct Plane { cols: usize, rows: usize, } const my_plane: Plane = Plane { cols: 8, rows: 128}; #[derive(Debug, thiserror::Error, PartialEq)] enum ParseError { #[error("Expected {0}")] Expected(&'static str), } #[derive(Debug, PartialEq)] struct Seat { col: usize, row: usize, } impl FromStr for Seat { type Err = ParseError; fn from_str(s: &str) -> Result { if s.len() != 10 { return Err(ParseError::Expected("10-char string")) } // split_at not supposed to fail as we are only working with ASCII chars here let s_bit = s .replace("F", "0") .replace("B", "1") .replace("R","1") .replace("L", "0") .chars() .collect::(); let (rowcode, colcode) = s_bit.split_at(7); Ok(Self { row: usize::from_str_radix(&rowcode, 2).unwrap(), col: usize::from_str_radix(&colcode, 2).unwrap(), }) } } impl Seat { fn seat_id(&self) -> usize { 8 * self.row + self.col } } fn main() { let input = include_str!("../data/input.txt"); let mut seat_ids: Vec = input.lines().map(|l| Seat::from_str(l).unwrap().seat_id()).collect(); seat_ids.sort(); println!("Max seat id: {:?}", seat_ids.iter().max()); let banana = seat_ids .windows(2) .flat_map(<&[usize;2]>::try_from) // Because windows() makes no promise on slice size .find(|[a, b]| *b == *a + 2); eprintln!("banana = {:#?}", banana); } #[cfg(test)] mod tests { use super::*; const AOC_INPUT: &str = "FBFBBFFRLR"; #[test] fn test_build_seat() { assert_eq!( Seat::from_str(AOC_INPUT), Ok(Seat { row: 44, col: 5 }) ); } #[test] fn test_seat_id() { assert_eq!( Seat::from_str(AOC_INPUT).unwrap().seat_id(), 357 ); } }