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,
|
node: u16,
|
||||||
goal: u16,
|
goal: u16,
|
||||||
map: &HashMap<u16, HashSet<u16>>,
|
map: &HashMap<u16, HashSet<u16>>,
|
||||||
used: &HashSet<u16>,
|
used: &mut HashSet<u16>,
|
||||||
cache: &mut HashMap<(u16, u16), usize>,
|
cache: &mut HashMap<(u16, u16), usize>,
|
||||||
) -> usize {
|
) -> usize {
|
||||||
if node == goal {
|
if node == goal {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
let mut ret = 0;
|
let mut ret = 0;
|
||||||
let mut used = used.clone();
|
|
||||||
// println!("+{}", node);
|
// println!("+{}", node);
|
||||||
for next in map.get(&node).iter().map(|v| v.iter()).flatten() {
|
for next in map.get(&node).iter().map(|v| v.iter()).flatten() {
|
||||||
if !used.insert(*next) {
|
if used.contains(next) {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
used.insert(*next);
|
||||||
let value = match cache.get(&(node, *next)) {
|
let value = match cache.get(&(node, *next)) {
|
||||||
Some(value) => *value,
|
Some(value) => *value,
|
||||||
None => {
|
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);
|
cache.insert((node, *next), value);
|
||||||
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 day08;
|
||||||
pub mod day09;
|
pub mod day09;
|
||||||
pub mod day10;
|
pub mod day10;
|
||||||
|
pub mod day11;
|
||||||
aoc_lib! { year = 2020 }
|
aoc_lib! { year = 2020 }
|
||||||
|
|
Loading…
Reference in a new issue