[TASK] Completed Day11 Part 1 (although I'm not happy with the performance...)

This commit is contained in:
2020-12-11 10:34:01 +01:00
parent 7910024d93
commit 6a135d0369
5 changed files with 258 additions and 3 deletions

View File

@@ -75,6 +75,4 @@ fn count_arrangements(adapters: &Vec<u32>, start_idx: usize, end_idx: usize, sol
solution_cache[start_idx] = res;
return res;
}

152
src/day11.rs Normal file
View File

@@ -0,0 +1,152 @@
use super::util;
use crate::day11::GridState::Floor;
use crate::day11::GridState::FilledSeat;
use crate::day11::GridState::EmptySeat;
// use std::mem::swap;
pub fn solve() {
let lines = util::read_file("input/day11.txt");
let seats = Seats::parse(&lines);
let part1 = solve_part1(&seats);
println!("Day 11 Part 1: {}", part1);
}
fn solve_part1(seats: &Seats) -> usize {
let mut last_seats = seats.clone();
let mut next_seats = seats.clone();
loop {
let mut changes = false;
for y in 0..seats.height {
for x in 0..seats.width {
let seat = last_seats.get(&x, &y);
if seat != &Floor {
let occupied = last_seats.count_occupied_neighbors(&x, &y);
if seat == &EmptySeat && occupied == 0 {
changes = true;
next_seats.set(&x, &y, FilledSeat);
} else if seat == &FilledSeat && occupied >= 4 {
next_seats.set(&x, &y, EmptySeat);
changes = true;
}
}
}
}
// next_seats.print();
if !changes {
break;
}
last_seats = next_seats.clone();
}
return last_seats.grid.iter().filter(|s| s == &&FilledSeat).count();
}
#[derive(Clone)]
struct Seats {
grid: Vec<GridState>,
width: usize,
height: usize,
}
const ONE: usize = 1;
impl Seats {
fn parse(lines: &Vec<String>) -> Seats {
let height = lines.len();
let width = lines[0].len();
let mut grid = vec!(GridState::Floor; width * height);
for y in 0..lines.len() {
let line = &lines[y];
let mut line_chars = line.chars();
for x in 0..lines[0].len() {
grid[x + y * width] = GridState::parse(&line_chars.next().unwrap())
}
}
return Seats { grid, width, height };
}
fn count_occupied_neighbors(&self, x: &usize, y: &usize) -> u8 {
let x_upper = x == &(self.width - &ONE);
let x_lower = x == &0;
let y_upper = y == &(self.height - &ONE);
let y_lower = y == &0;
return
if !x_lower && !y_lower && self.is_occupied(&(x - &ONE), &(y - &ONE)) { 1 } else { 0 } +
if !x_lower && self.is_occupied(&(x - &ONE), &y) { 1 } else { 0 } +
if !x_lower && !y_upper && self.is_occupied(&(x - &ONE), &(y + ONE)) { 1 } else { 0 } +
if !y_lower && self.is_occupied(&x, &(y - ONE)) { 1 } else { 0 } +
if !y_upper && self.is_occupied(&x, &(y + ONE)) { 1 } else { 0 } +
if !x_upper && !y_lower && self.is_occupied(&(x + ONE), &(y - ONE)) { 1 } else { 0 } +
if !x_upper && self.is_occupied(&(x + ONE), &y) { 1 } else { 0 } +
if !x_upper && !y_upper && self.is_occupied(&(x + ONE), &(y + ONE)) { 1 } else { 0 }
}
fn is_occupied(&self, x: &usize, y: &usize) -> bool {
self.get(x, y) == &FilledSeat
}
fn get(&self, x: &usize, y: &usize) -> &GridState {
return &self.grid[x + y * self.width];
}
fn set(&mut self, x: &usize, y: &usize, state: GridState) {
self.grid[x + y * self.width] = state;
}
fn print(&self) {
for y in 0..self.height {
for x in 0..self.width {
print!("{}", self.get(&x, &y).to_char())
}
println!();
}
}
}
impl PartialEq for Seats {
fn eq(&self, other: &Self) -> bool {
return self.width == other.width && self.height == other.height && self.grid == other.grid;
}
}
#[derive(Eq, PartialEq, Copy, Clone)]
enum GridState {
EmptySeat, FilledSeat, Floor
}
impl GridState {
fn parse(c: &char) -> GridState {
return match c {
'.' => GridState::Floor,
'L' => GridState::EmptySeat,
'#' => GridState::FilledSeat,
_ => panic!("Unknown grid state")
}
}
fn to_char(&self) -> char {
return match self {
GridState::Floor => '.',
GridState::EmptySeat => 'L',
GridState::FilledSeat => '#'
}
}
}

View File

@@ -12,8 +12,9 @@ mod day7;
mod day8;
mod day9;
mod day10;
mod day11;
const MAX_DAY: u8 = 10;
const MAX_DAY: u8 = 11;
const BENCHMARK_AMOUNT: u32 = 100;
fn solve(day: u8) {
@@ -28,6 +29,7 @@ fn solve(day: u8) {
8 => day8::solve(),
9 => day9::solve(),
10 => day10::solve(),
11 => day11::solve(),
_ => println!("This day is not yet implemented")
}
}