AoC2020/src/bin/day11_part2.rs

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