82 lines
2.0 KiB
Rust
82 lines
2.0 KiB
Rust
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<Self, Self::Err> {
|
|
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::<String>();
|
|
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<usize> = 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
|
|
);
|
|
}
|
|
} |