[TASK] Finally finished day 11
This commit is contained in:
7
Cargo.lock
generated
7
Cargo.lock
generated
@@ -6,6 +6,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"regex",
|
||||
"usize_cast",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -55,3 +56,9 @@ checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "usize_cast"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "810f3a98a85147e3ad2a1331aa6dac66490e802d65fa0ab283c383058e3f9751"
|
||||
|
||||
@@ -8,4 +8,5 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
regex = "1"
|
||||
lazy_static = "1.4.0"
|
||||
lazy_static = "1.4.0"
|
||||
usize_cast = "1.0.0"
|
||||
103
src/day11.rs
103
src/day11.rs
@@ -2,17 +2,21 @@ use super::util;
|
||||
use crate::day11::GridState::Floor;
|
||||
use crate::day11::GridState::FilledSeat;
|
||||
use crate::day11::GridState::EmptySeat;
|
||||
// use std::mem::swap;
|
||||
use usize_cast::{IntoUsize, FromUsize, IntoIsize, FromIsize};
|
||||
|
||||
pub fn solve() {
|
||||
let lines = util::read_file("input/day11.txt");
|
||||
|
||||
let seats = Seats::parse(&lines);
|
||||
let visible_chairs = seats.calculate_all_visible_chairs();
|
||||
|
||||
let part1 = solve_part1(&seats);
|
||||
|
||||
println!("Day 11 Part 1: {}", part1);
|
||||
|
||||
let part2 = solve_part2(&seats, &visible_chairs);
|
||||
|
||||
println!("Day 11 Part 2: {}", part2);
|
||||
}
|
||||
|
||||
fn solve_part1(seats: &Seats) -> usize {
|
||||
@@ -45,7 +49,38 @@ fn solve_part1(seats: &Seats) -> usize {
|
||||
last_seats = next_seats.clone();
|
||||
}
|
||||
return last_seats.grid.iter().filter(|s| s == &&FilledSeat).count();
|
||||
}
|
||||
|
||||
fn solve_part2(seats: &Seats, visible_chairs: &Vec<Option<Vec<(usize, usize)>>>) -> 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_visible_chairs(&x, &y, visible_chairs);
|
||||
if seat == &EmptySeat && occupied == 0 {
|
||||
changes = true;
|
||||
next_seats.set(&x, &y, FilledSeat);
|
||||
} else if seat == &FilledSeat && occupied >= 5 {
|
||||
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)]
|
||||
@@ -58,6 +93,8 @@ struct Seats {
|
||||
const ONE: usize = 1;
|
||||
impl Seats {
|
||||
|
||||
const DIRECTIONS: [(i32, i32); 8] = [(-1, 1), (-1, 0), (-1, -1), (0, -1), (0, 1), (1, 1), (1, 0), (1, -1)];
|
||||
|
||||
fn parse(lines: &Vec<String>) -> Seats {
|
||||
|
||||
let height = lines.len();
|
||||
@@ -71,7 +108,69 @@ impl Seats {
|
||||
}
|
||||
}
|
||||
|
||||
return Seats { grid, width, height };
|
||||
let mut seats = Seats { grid, width, height };
|
||||
seats.calculate_all_visible_chairs();
|
||||
return seats;
|
||||
}
|
||||
|
||||
fn calculate_all_visible_chairs(&self) -> Vec<Option<Vec<(usize, usize)>>> {
|
||||
|
||||
let mut visible_chairs = vec!(Option::None; self.width * self.height);
|
||||
for y in 0..self.height {
|
||||
for x in 0..self.width {
|
||||
|
||||
if self.get(&x, &y) != &Floor {
|
||||
visible_chairs[x + y * self.width] = Option::Some(self.calculate_visible_chairs(&x, &y))
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return visible_chairs;
|
||||
}
|
||||
|
||||
fn calculate_visible_chairs(&self, x: &usize, y: &usize) -> Vec<(usize, usize)> {
|
||||
|
||||
return Seats::DIRECTIONS.iter()
|
||||
.map(|d| self.raycast(x, y, d))
|
||||
.filter(|c| c.is_some())
|
||||
.map(|c| c.unwrap())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
}
|
||||
|
||||
fn raycast(&self, origin_x: &usize, origin_y: &usize, direction: &(i32, i32)) -> Option<(usize, usize)> {
|
||||
|
||||
let mut hit = false;
|
||||
let mut x = *origin_x as i32;
|
||||
let mut y = *origin_y as i32;
|
||||
while !hit {
|
||||
|
||||
|
||||
x = x + direction.0;
|
||||
y = y + direction.1;
|
||||
|
||||
if !self.is_valid(&x, &y) {
|
||||
return Option::None;
|
||||
}
|
||||
|
||||
if self.get(&(x as usize), &(y as usize)) != &Floor {
|
||||
return Option::Some((x as usize, y as usize));
|
||||
}
|
||||
}
|
||||
return Option::None;
|
||||
}
|
||||
|
||||
fn is_valid(&self, x: &i32, y: &i32) -> bool {
|
||||
return x >= &0 && x < &(self.width as i32) && y >= &0 && y < &(self.height as i32);
|
||||
}
|
||||
|
||||
fn count_occupied_visible_chairs(&self, x: &usize, y: &usize, visible_chairs: &Vec<Option<Vec<(usize, usize)>>>) -> u8 {
|
||||
|
||||
return visible_chairs.get(x + y * self.width).unwrap().as_ref().unwrap().iter()
|
||||
.filter(|c| self.get(&c.0, &c.1) == &FilledSeat)
|
||||
.count() as u8;
|
||||
|
||||
}
|
||||
|
||||
fn count_occupied_neighbors(&self, x: &usize, y: &usize) -> u8 {
|
||||
|
||||
@@ -10,4 +10,12 @@ pub fn read_file(filename: &str) -> Vec<String> {
|
||||
|
||||
res
|
||||
|
||||
}
|
||||
|
||||
pub fn add_to_usize(u: usize, i: i32) -> usize {
|
||||
if i.is_negative() {
|
||||
u - i.wrapping_abs() as u32 as usize
|
||||
} else {
|
||||
u + i as usize
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user