Day 11
This commit is contained in:
parent
cc1cb04b33
commit
fd583e70e4
3 changed files with 192 additions and 5 deletions
10
src/day10.rs
10
src/day10.rs
|
@ -14,23 +14,23 @@ fn solve_part_2_rec(
|
|||
node: u16,
|
||||
goal: u16,
|
||||
map: &HashMap<u16, HashSet<u16>>,
|
||||
used: &HashSet<u16>,
|
||||
used: &mut HashSet<u16>,
|
||||
cache: &mut HashMap<(u16, u16), usize>,
|
||||
) -> usize {
|
||||
if node == goal {
|
||||
return 1;
|
||||
}
|
||||
let mut ret = 0;
|
||||
let mut used = used.clone();
|
||||
// println!("+{}", node);
|
||||
for next in map.get(&node).iter().map(|v| v.iter()).flatten() {
|
||||
if !used.insert(*next) {
|
||||
if used.contains(next) {
|
||||
continue;
|
||||
};
|
||||
used.insert(*next);
|
||||
let value = match cache.get(&(node, *next)) {
|
||||
Some(value) => *value,
|
||||
None => {
|
||||
let value = solve_part_2_rec(*next, goal, map, &used, cache);
|
||||
let value = solve_part_2_rec(*next, goal, map, used, cache);
|
||||
cache.insert((node, *next), value);
|
||||
value
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ impl Data {
|
|||
}
|
||||
}
|
||||
}
|
||||
return solve_part_2_rec(0, goal, &map, &HashSet::new(), &mut HashMap::new());
|
||||
return solve_part_2_rec(0, goal, &map, &mut HashSet::new(), &mut HashMap::new());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
186
src/day11.rs
Normal file
186
src/day11.rs
Normal file
|
@ -0,0 +1,186 @@
|
|||
use aoc_runner_derive::{aoc, aoc_generator};
|
||||
use std::io::Write;
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||
pub enum Seat {
|
||||
Floor,
|
||||
Empty,
|
||||
Occupied,
|
||||
}
|
||||
|
||||
pub struct Data(Vec<Vec<Seat>>);
|
||||
|
||||
impl Data {
|
||||
fn print(&self) {
|
||||
for row in &self.0 {
|
||||
for seat in row {
|
||||
let c = match seat {
|
||||
Seat::Floor => '.',
|
||||
Seat::Empty => 'L',
|
||||
Seat::Occupied => '#',
|
||||
};
|
||||
print!("{}", c);
|
||||
}
|
||||
println!("");
|
||||
}
|
||||
}
|
||||
fn count_nb_p1(&self, x: usize, y: usize) -> usize {
|
||||
let mut ret = 0;
|
||||
for dy in &[-1i64, 0, 1] {
|
||||
for dx in &[-1i64, 0, 1] {
|
||||
if *dx == 0 && *dy == 0 {
|
||||
continue;
|
||||
}
|
||||
let x = ((x as i64) + dx) as usize;
|
||||
let y = ((y as i64) + dy) as usize;
|
||||
if let Some(v) = self.0.get(y).map(|v| v.get(x)).flatten() {
|
||||
match v {
|
||||
Seat::Occupied => {
|
||||
ret += 1;
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
fn count_nb_p2(&self, x: usize, y: usize) -> usize {
|
||||
let mut ret = 0;
|
||||
for dy in &[-1i64, 0, 1] {
|
||||
for dx in &[-1i64, 0, 1] {
|
||||
if *dx == 0 && *dy == 0 {
|
||||
continue;
|
||||
}
|
||||
for l in 1.. {
|
||||
let x = (x as i64) + dx * l;
|
||||
let y = (y as i64) + dy * l;
|
||||
if x < 0 || y < 0 {
|
||||
break;
|
||||
}
|
||||
if let Some(v) = self.0.get(y as usize).map(|v| v.get(x as usize)).flatten() {
|
||||
match v {
|
||||
Seat::Occupied => {
|
||||
ret += 1;
|
||||
break;
|
||||
}
|
||||
Seat::Empty => {
|
||||
break;
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
fn update_p1(&mut self) -> bool {
|
||||
let mut data = self.0.clone();
|
||||
for (y, row) in self.0.iter().enumerate() {
|
||||
for (x, seat) in row.iter().enumerate() {
|
||||
let occupied = self.count_nb_p1(x, y);
|
||||
match seat {
|
||||
Seat::Floor => {}
|
||||
Seat::Empty => {
|
||||
if occupied == 0 {
|
||||
data[y][x] = Seat::Occupied;
|
||||
}
|
||||
}
|
||||
Seat::Occupied => {
|
||||
if occupied > 3 {
|
||||
data[y][x] = Seat::Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let changed = data != self.0;
|
||||
self.0 = data;
|
||||
return changed;
|
||||
}
|
||||
|
||||
fn update_p2(&mut self) -> bool {
|
||||
let mut data = self.0.clone();
|
||||
for (y, row) in self.0.iter().enumerate() {
|
||||
for (x, seat) in row.iter().enumerate() {
|
||||
let occupied = self.count_nb_p2(x, y);
|
||||
match seat {
|
||||
Seat::Floor => {}
|
||||
Seat::Empty => {
|
||||
if occupied == 0 {
|
||||
data[y][x] = Seat::Occupied;
|
||||
}
|
||||
}
|
||||
Seat::Occupied => {
|
||||
if occupied > 4 {
|
||||
data[y][x] = Seat::Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let changed = data != self.0;
|
||||
self.0 = data;
|
||||
return changed;
|
||||
}
|
||||
}
|
||||
|
||||
#[aoc_generator(day11)]
|
||||
pub fn input_generator(input: &str) -> Data {
|
||||
let ret: Vec<Vec<_>> = input
|
||||
.trim()
|
||||
.lines()
|
||||
.map(|line| {
|
||||
line.trim()
|
||||
.chars()
|
||||
.map(|c| match c {
|
||||
'L' => Seat::Empty,
|
||||
'#' => Seat::Occupied,
|
||||
'.' => Seat::Floor,
|
||||
c => panic!("invalid character: {:?}", c),
|
||||
})
|
||||
.collect()
|
||||
})
|
||||
.collect();
|
||||
for line in &ret {
|
||||
if ret[0].len() != line.len() {
|
||||
panic!("Non rectangular input!");
|
||||
}
|
||||
}
|
||||
Data(ret)
|
||||
}
|
||||
|
||||
#[aoc(day11, part1)]
|
||||
pub fn solve_part1(input: &Data) -> usize {
|
||||
let mut input = Data(input.0.clone());
|
||||
let mut n = 0;
|
||||
while input.update_p1() {}
|
||||
for row in &input.0 {
|
||||
for seat in row {
|
||||
if *seat == Seat::Occupied {
|
||||
n += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
#[aoc(day11, part2)]
|
||||
pub fn solve_part2(input: &Data) -> usize {
|
||||
let mut input = Data(input.0.clone());
|
||||
while input.update_p2() {}
|
||||
|
||||
let mut n = 0;
|
||||
for row in &input.0 {
|
||||
for seat in row {
|
||||
if *seat == Seat::Occupied {
|
||||
n += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
|
@ -9,4 +9,5 @@ pub mod day07;
|
|||
pub mod day08;
|
||||
pub mod day09;
|
||||
pub mod day10;
|
||||
pub mod day11;
|
||||
aoc_lib! { year = 2020 }
|
||||
|
|
Loading…
Reference in a new issue