This commit is contained in:
Daniel S. 2020-12-11 14:57:07 +01:00
parent cc1cb04b33
commit fd583e70e4
3 changed files with 192 additions and 5 deletions

View file

@ -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
View 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;
}

View file

@ -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 }