use std::error::Error; use std::fs::File; use std::io::{self, BufRead}; use std::vec::Vec; #[derive(PartialEq, Copy, Clone)] enum Seat { Floor, Empty, Occupied, } fn sees_occupied(x: usize, y: usize, slope: (i32, i32), seats: &Vec>) -> usize { let mut ix = x as i32; let mut iy = y as i32; loop { ix += slope.0; iy += slope.1; if iy < 0 || iy >= seats.len() as i32 || ix < 0 || ix >= seats[iy as usize].len() as i32 { return 0; } match seats[iy as usize][ix as usize] { Seat::Occupied => return 1, Seat::Empty => return 0, _ => {} }; } } fn count_occupied(x: usize, y: usize, seats: &Vec>) -> usize { sees_occupied(x, y, (-1, -1), seats) + sees_occupied(x, y, (0, -1), seats) + sees_occupied(x, y, (1, -1), seats) + sees_occupied(x, y, (-1, 0), seats) + sees_occupied(x, y, (1, 0), seats) + sees_occupied(x, y, (-1, 1), seats) + sees_occupied(x, y, (0, 1), seats) + sees_occupied(x, y, (1, 1), seats) } fn main() -> Result<(), Box> { let file = File::open("inputs/day11.txt")?; let lines = io::BufReader::new(file).lines().map(|l| l.unwrap()); let mut seats: Vec> = lines .map(|l| { l.chars() .map(|c| match c { '.' => Seat::Floor, 'L' => Seat::Empty, '#' => Seat::Occupied, _ => panic!("Unkown char {}", c), }) .collect() }) .collect(); let mut changed = true; while changed { changed = false; let mut next_seats: Vec> = Vec::new(); //print_seats(&seats); for y in 0..seats.len() { let mut next_row: Vec = Vec::new(); for x in 0..seats[y].len() { if seats[y][x] == Seat::Occupied && count_occupied(x, y, &seats) >= 5 { next_row.push(Seat::Empty); changed = true; } else if seats[y][x] == Seat::Empty && count_occupied(x, y, &seats) == 0 { next_row.push(Seat::Occupied); changed = true; } else { next_row.push(seats[y][x]); } } next_seats.push(next_row); } seats = next_seats; } let count = seats .iter() .map(|r| { r.iter() .map(|s| if *s == Seat::Occupied { 1 } else { 0 }) .fold(0, |x, acc| x + acc) }) .fold(0, |x, acc| x + acc); println!("Count: {}", count); Ok(()) }