98 lines
2.5 KiB
Rust
98 lines
2.5 KiB
Rust
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 is_occupied(x: i32, y: i32, seats: &Vec<Vec<Seat>>) -> usize {
|
|
if y >= 0
|
|
&& y < seats.len() as i32
|
|
&& x >= 0
|
|
&& x < seats[y as usize].len() as i32
|
|
&& seats[y as usize][x as usize] == Seat::Occupied
|
|
{
|
|
1
|
|
} else {
|
|
0
|
|
}
|
|
}
|
|
|
|
fn count_adjacent(x: usize, y: usize, seats: &Vec<Vec<Seat>>) -> usize {
|
|
let ix = x as i32;
|
|
let iy = y as i32;
|
|
|
|
is_occupied(ix - 1, iy - 1, seats)
|
|
+ is_occupied(ix, iy - 1, seats)
|
|
+ is_occupied(ix + 1, iy - 1, seats)
|
|
+ is_occupied(ix - 1, iy, seats)
|
|
+ is_occupied(ix + 1, iy, seats)
|
|
+ is_occupied(ix - 1, iy + 1, seats)
|
|
+ is_occupied(ix, iy + 1, seats)
|
|
+ is_occupied(ix + 1, iy + 1, seats)
|
|
}
|
|
|
|
fn main() -> Result<(), Box<dyn Error>> {
|
|
let file = File::open("inputs/day11.txt")?;
|
|
let lines = io::BufReader::new(file).lines().map(|l| l.unwrap());
|
|
|
|
let mut seats: Vec<Vec<Seat>> = 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<Seat>> = Vec::new();
|
|
|
|
//print_seats(&seats);
|
|
|
|
for y in 0..seats.len() {
|
|
let mut next_row: Vec<Seat> = Vec::new();
|
|
for x in 0..seats[y].len() {
|
|
if seats[y][x] == Seat::Occupied && count_adjacent(x, y, &seats) >= 4 {
|
|
next_row.push(Seat::Empty);
|
|
changed = true;
|
|
} else if seats[y][x] == Seat::Empty && count_adjacent(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(())
|
|
}
|