AoC2020/src/bin/day11.rs

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(())
}