From fd583e70e4a2f4142793c71ca2a015979c84b61a Mon Sep 17 00:00:00 2001 From: Daniel Seiller Date: Fri, 11 Dec 2020 14:57:07 +0100 Subject: [PATCH] Day 11 --- src/day10.rs | 10 +-- src/day11.rs | 186 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 1 + 3 files changed, 192 insertions(+), 5 deletions(-) create mode 100644 src/day11.rs diff --git a/src/day10.rs b/src/day10.rs index 27fdbce..202222b 100644 --- a/src/day10.rs +++ b/src/day10.rs @@ -14,23 +14,23 @@ fn solve_part_2_rec( node: u16, goal: u16, map: &HashMap>, - used: &HashSet, + used: &mut HashSet, 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()); } } diff --git a/src/day11.rs b/src/day11.rs new file mode 100644 index 0000000..7875d11 --- /dev/null +++ b/src/day11.rs @@ -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>); + +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> = 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; +} diff --git a/src/lib.rs b/src/lib.rs index c3798d3..f861ba5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,4 +9,5 @@ pub mod day07; pub mod day08; pub mod day09; pub mod day10; +pub mod day11; aoc_lib! { year = 2020 }