101 lines
2.7 KiB
Rust
101 lines
2.7 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 sees_occupied(x: usize, y: usize, slope: (i32, i32), seats: &Vec<Vec<Seat>>) -> 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<Vec<Seat>>) -> 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<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_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(())
|
|
}
|