2022 day 23 rust
This commit is contained in:
parent
03c7d0a04c
commit
2f381d6158
73
2022/rust/inputs/day23.txt
Normal file
73
2022/rust/inputs/day23.txt
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
.#....#...##....##.#.###..##..#..#.#.###....#.###.###.##..###......#..##.
|
||||||
|
...#.##.#..#.#.######...##..#.#...#########.#.######..#.#.#.#...###.#.#.#
|
||||||
|
###.#.####.#.##.##....##..###.##..##..#.###.#.#.##...#######...###.##...#
|
||||||
|
.#...#####.##......##.#..###....###..#..#...###..##..##.#.##.###.#.######
|
||||||
|
.#...#...#.###.....##.##.########.#.##...##..##..#....#.####.###.##......
|
||||||
|
#####.......###..##..##...#..#.....#..#..##.##...##..........#.#.##.#.###
|
||||||
|
##..###.#.###.###.#....#...###....#...#.###..##.##.###.#.#.#..###..##.##.
|
||||||
|
#......#..###....#..###.###.#.#..##..##.###.#.#..#.#.###..###..#..##.##.#
|
||||||
|
#..####....#.#..#.#.....#...#.##.##.##...#.##.#.#..#.##.#####..##.#.##.#.
|
||||||
|
.#######..#####.#.#.#...##.#.####.#.#.##....##.##..####..####.#..##..###.
|
||||||
|
.#.##.###.#######.#...#.##...###........#.###..#.###....#..#....#.##.##..
|
||||||
|
.#.#.####..##.#.#####.#.....##.###.#..##.##...##.###....####...##.#.#####
|
||||||
|
#..#..#.##.#....#.#.#.##.##...##..##.####..#..##......##.####..#.##.#.##.
|
||||||
|
#.#.#.##....##..####.###....####...####..#..##..#.#..........#.##..###..#
|
||||||
|
.#....###.#.#.#.####...######.#.##.......##..#..##.#...#...##.....####.#.
|
||||||
|
#.....#.#.###.##..##....##.##.##.#.##..##.##...###...#..#....#.#.##.#....
|
||||||
|
.##.#.#####.#......#..##.###..#..#..###.#........####.#.####.#.##.#####.#
|
||||||
|
..##.#.#..........#..#.##..#.#.#.....##.#.#.#######..#.##.###.#..#.#####.
|
||||||
|
.##..#.####.....#.#..#..###.##..###.##.##.#####..#.#.###...#.##.#.####.##
|
||||||
|
###.#.######...###...#..#..##.#####..#.#..#...##.#.#.#.##......#.##..#.##
|
||||||
|
#..#...#...#.##########.###..#.#.##..#.#..#####..######.###....##.##....#
|
||||||
|
##...#######..#######.#......###..##.#.##.####..###.###.#####..######.#.#
|
||||||
|
.###.####.#.#.##..####...##.##..#....#.#.#.#...#....#.##..#..#.....##.#.#
|
||||||
|
##..........#....##...#######.#.#####.##....##..#.#.##.#.#..#...##.##..##
|
||||||
|
##.......##..#.##...#..#..###.#.##......##...#.#...###..#....#..##.#.#...
|
||||||
|
#####.###....######.#.######.####..##..#..#.#....#######....##.###..##..#
|
||||||
|
##..#..#..##.#...##.#####.#.##..##...#..##.....#.#.#....##.##.#..#....###
|
||||||
|
..###.##.....#....###.#..#####.#.###.#.#..###.########....#.#.##........#
|
||||||
|
##.#...#...###..###.####..###.#######..######...##.#...#.#.#.###..##.#...
|
||||||
|
...#.#...####...###.##.##.##..#.#..##.#.#.####...#.#.....#...#..##....#..
|
||||||
|
####...#.#.#.......####.#..#..####.#..###.#......#..###...#.#.##...#....#
|
||||||
|
##......##...#.##..#.#...#####...#.#####....#....###.#..#...#....##.#..#.
|
||||||
|
...#####...#.....##.#.##.##..#.#..###.#.##.#####...##..#.#.##.##...###.#.
|
||||||
|
..#...##..####...##.###..#...#......##...##.#.#.###.#.#...#..#...#...####
|
||||||
|
.##.###.#.#.#.###.##...#.#.#...#.#...##..#.#....####.##...###..##..#...#.
|
||||||
|
.##.#####.#..##.##....##.##.#..##.#..##.#..#.##.###.....#..##.###.##...##
|
||||||
|
#.#...####..#.#....##...##..#...##...##.##.##.#..#.#.......####.#.###..#.
|
||||||
|
##.#.##...#.#.#..#.#..##.#.#.##..#....#..###.##.##.##.....#..#..###.##.#.
|
||||||
|
...#...#.#......########.###.#.#.###.####.#.#.####...#.#.#.....#...###...
|
||||||
|
....###.#.#..##..#.#.#.##.###.###.....###.##.##.##.#.##..#...#.####..##.#
|
||||||
|
#....###.........#.##..#..#.##.##....#.##..#.#.##......#.##.#..##..##....
|
||||||
|
#....####.#....####.##.#.#...#.####.#.#.##..#.##.####...#..##.##.##.#.##.
|
||||||
|
...##..#..#...##.#.#.#.####...#.#...#.#.#.###..#.###..#..##.#.#..#####...
|
||||||
|
..#####..######.##.##..#.####.#.#..#...#....#.#..#########..##.#.####.##.
|
||||||
|
#..#.#...#.####...#......#.#...#.#.###..#..#.#....#..#..##..#..##.#......
|
||||||
|
#.####...#######..###.#.#..##...##.#...#####...##....#.##.#.#.###..##.###
|
||||||
|
####..###...##..######..#####..#...#####...#.#.####.##.....##....#.#...##
|
||||||
|
.#####.#..##.###.......###.######.#######.#.##..###.###...#.#...#..#####.
|
||||||
|
.##.###...##..##..#.###.#.##.###...###...##.#...#..##.##...####.###...##.
|
||||||
|
#..#..#..##..#.#.#.##....##..#...##.##....##.###.##.#....#...#....#####..
|
||||||
|
.#..#..######...#.#.##.###.###.#.#...#.#....#..#..##.##..#..####...#.###.
|
||||||
|
##.##.#####..###.##.#.#.###......###.#.##....###..#..####.###......##....
|
||||||
|
#.#.###..#..###.#....#.#....##.#...#.##.####.#.##......#.#..##.#....#..##
|
||||||
|
####..##.#..#...###....#.##...#..#.#...#.####....##..#..##...#..#.....#..
|
||||||
|
..#..###.#..#.##....#######..##......#.##...##.##.##.##..#.#..##.##......
|
||||||
|
.##.#.#.###....####.#.#.###..#.###....#..#..###..##..###.#..#.##.#..####.
|
||||||
|
..###..##.##...#..#...#...#.#.##..####.#..#..#.#..######.##.#.##....#.#..
|
||||||
|
..###.......##.#.##.####.##...##.#######.#..#..###..#.#.##.#...##.###.##.
|
||||||
|
##.#..#.##.#.###.####..#.##.......###.########.#.#....#.#...###.#.#.#..##
|
||||||
|
#.#..#..##...####...#...#.###.##...##.....#...#..#.####.#.#.##.#####.....
|
||||||
|
.######.#..#..#...#..#..#..##.##.##...#....##.#.#.##.###..##....#########
|
||||||
|
##....#...#.###...########.#####.#######.#...#.##.#..#..#.###.#.######.##
|
||||||
|
.###.#....##.#.#.#.#.##..#####.####.###.#..#.##..##..##..##.....#.#.#####
|
||||||
|
#.#.###.#..##...###.#.....###.##..##.....##.###.####..###.#...#..##.###.#
|
||||||
|
#####.#####.#...##.######.#..#.####.##.#.#..#.....####.#...#.#.....##..##
|
||||||
|
.#.#.#.###.#.#.##.##...#####...#.....##.##.#######..#####.#.##..##...##..
|
||||||
|
#.#...##.#.###...##.#.#.##.#....####....#.#.#..#..##.####.##..#.#.....##.
|
||||||
|
.##.#.##..#####..#..#.#.###..##.#....######..##...###.#...##..##.#....###
|
||||||
|
.##...#..#.#######.#.#...##.##.##.#...##....#.###.#....#.#..##.###..#.###
|
||||||
|
####.#....#.#..#.#...#..#..#..##....##..####.#.####.#..#..#..#.#..#.#.##.
|
||||||
|
.####..#.##..#.#.###...########.##.##...#.##....##..##.#.####...#..#.##..
|
||||||
|
###.#.#...#.#...##.#.###......##...###.#..#.##.########.###......###.####
|
||||||
|
##..#####..#.#.##.#######.######....#.###..#.#...#...#.###.#.##..#...##..
|
|
@ -1,4 +1,4 @@
|
||||||
use std::collections::HashSet;
|
use std::collections::{HashMap, HashSet, VecDeque};
|
||||||
use crate::utils;
|
use crate::utils;
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,26 +11,154 @@ pub fn run() -> () {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
type Location = (isize, isize);
|
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||||
|
struct Loc {
|
||||||
|
row: isize,
|
||||||
fn solve1(data: &HashSet<Location>) -> i32 {
|
col: isize
|
||||||
println!("{:?}", data);
|
|
||||||
1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn solve2(data: &HashSet<Location>) -> i32 {
|
impl Loc {
|
||||||
2
|
fn n(&self) -> Self { Self { row: self.row - 1, col: self.col } }
|
||||||
|
fn s(&self) -> Self { Self { row: self.row + 1, col: self.col } }
|
||||||
|
fn w(&self) -> Self { Self { row: self.row, col: self.col - 1 } }
|
||||||
|
fn e(&self) -> Self { Self { row: self.row, col: self.col + 1 } }
|
||||||
|
fn nw(&self) -> Self { Self { row: self.row - 1, col: self.col - 1 } }
|
||||||
|
fn ne(&self) -> Self { Self { row: self.row - 1, col: self.col + 1 } }
|
||||||
|
fn sw(&self) -> Self { Self { row: self.row + 1, col: self.col - 1 } }
|
||||||
|
fn se(&self) -> Self { Self { row: self.row + 1, col: self.col + 1 } }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn has_neighbors(occupied: &HashSet<Loc>, loc: Loc) -> bool {
|
||||||
|
[loc.n(), loc.s(), loc.w(), loc.e(), loc.nw(), loc.ne(), loc.sw(), loc.se()].into_iter().any(|loc| occupied.contains(&loc))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn move_n(occupied: &HashSet<Loc>, loc: Loc) -> Option<Loc> {
|
||||||
|
let nn = !occupied.contains(&loc.n());
|
||||||
|
let ne = !occupied.contains(&loc.ne());
|
||||||
|
let nw = !occupied.contains(&loc.nw());
|
||||||
|
(nn && ne && nw).then_some(loc.n())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn move_s(occupied: &HashSet<Loc>, loc: Loc) -> Option<Loc> {
|
||||||
|
let ss = !occupied.contains(&loc.s());
|
||||||
|
let se = !occupied.contains(&loc.se());
|
||||||
|
let sw = !occupied.contains(&loc.sw());
|
||||||
|
(ss && se && sw).then_some(loc.s())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn move_w(occupied: &HashSet<Loc>, loc: Loc) -> Option<Loc> {
|
||||||
|
let ww = !occupied.contains(&loc.w());
|
||||||
|
let nw = !occupied.contains(&loc.nw());
|
||||||
|
let sw = !occupied.contains(&loc.sw());
|
||||||
|
(ww && nw && sw).then_some(loc.w())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn move_e(occupied: &HashSet<Loc>, loc: Loc) -> Option<Loc> {
|
||||||
|
let ee = !occupied.contains(&loc.e());
|
||||||
|
let ne = !occupied.contains(&loc.ne());
|
||||||
|
let se = !occupied.contains(&loc.se());
|
||||||
|
(ee && ne && se).then_some(loc.e())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn find_bounds(locs: &HashSet<Loc>) -> ((isize, isize), (isize, isize)) {
|
||||||
|
locs.iter().fold(((isize::MAX, isize::MIN), (isize::MAX, isize::MIN)), |((r_min, r_max), (c_min, c_max)), loc| {
|
||||||
|
((r_min.min(loc.row), r_max.max(loc.row)), (c_min.min(loc.col), c_max.max(loc.col)))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw(elves: &Vec<Loc>) {
|
||||||
|
let elves = HashSet::<Loc>::from_iter(elves.iter().copied());
|
||||||
|
let ((r_min, r_max), (c_min, c_max)) = find_bounds(&elves);
|
||||||
|
|
||||||
|
for row in r_min..=r_max {
|
||||||
|
for col in c_min..=c_max {
|
||||||
|
match elves.contains(&Loc { row, col }) {
|
||||||
|
true => print!("#"),
|
||||||
|
false => print!("."),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn count_empty(elves: &Vec<Loc>) -> i32 {
|
||||||
|
let elves = HashSet::<Loc>::from_iter(elves.iter().copied());
|
||||||
|
let ((r_min, r_max), (c_min, c_max)) = find_bounds(&elves);
|
||||||
|
|
||||||
|
let mut sum = 0;
|
||||||
|
for row in r_min..=r_max {
|
||||||
|
for col in c_min..=c_max {
|
||||||
|
if !elves.contains(&Loc { row, col }) {
|
||||||
|
sum += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sum
|
||||||
|
}
|
||||||
|
|
||||||
|
fn solve1(data: &HashSet<Loc>) -> i32 {
|
||||||
|
let mut elves = Vec::from_iter(data.iter().copied());
|
||||||
|
let mut moves = VecDeque::from([move_n, move_s, move_w, move_e]);
|
||||||
|
|
||||||
|
for _ in 0..10 {
|
||||||
|
let occupied = HashSet::<Loc>::from_iter(elves.iter().copied());
|
||||||
|
let mut planned = HashMap::<Loc, Vec<usize>>::new();
|
||||||
|
for (index, &loc) in elves.iter().enumerate().filter(|&(_, loc)| has_neighbors(&occupied, *loc)) {
|
||||||
|
if let Some(loc) = moves.iter().filter_map(|f| f(&occupied, loc)).next() {
|
||||||
|
planned.entry(loc)
|
||||||
|
.and_modify(|v| v.push(index))
|
||||||
|
.or_insert(vec![index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (loc, planned) in planned.into_iter().filter(|(_, vec)| vec.len() == 1) {
|
||||||
|
elves[planned[0]] = loc;
|
||||||
|
}
|
||||||
|
|
||||||
|
moves.rotate_left(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
count_empty(&elves)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn solve2(data: &HashSet<Loc>) -> i32 {
|
||||||
|
let mut elves = Vec::from_iter(data.iter().copied());
|
||||||
|
let mut moves = VecDeque::from([move_n, move_s, move_w, move_e]);
|
||||||
|
|
||||||
|
for round in 1..i32::MAX {
|
||||||
|
let occupied = HashSet::<Loc>::from_iter(elves.iter().copied());
|
||||||
|
let mut planned = HashMap::<Loc, Vec<usize>>::new();
|
||||||
|
for (index, &loc) in elves.iter().enumerate().filter(|&(_, loc)| has_neighbors(&occupied, *loc)) {
|
||||||
|
if let Some(loc) = moves.iter().filter_map(|f| f(&occupied, loc)).next() {
|
||||||
|
planned.entry(loc)
|
||||||
|
.and_modify(|v| v.push(index))
|
||||||
|
.or_insert(vec![index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let changes = planned.into_iter().filter(|(_, vec)| vec.len() == 1).collect::<Vec<_>>();
|
||||||
|
if changes.len() == 0 { return round }
|
||||||
|
|
||||||
|
for (loc, planned) in changes {
|
||||||
|
elves[planned[0]] = loc;
|
||||||
|
}
|
||||||
|
|
||||||
|
moves.rotate_left(1);
|
||||||
|
};
|
||||||
|
panic!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn parse_data<T: AsRef<str>>(data: &[T]) -> HashSet<Location> {
|
fn parse_data<T: AsRef<str>>(data: &[T]) -> HashSet<Loc> {
|
||||||
data.iter()
|
data.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.flat_map(|(row, line)| line.as_ref()
|
.flat_map(|(row, line)| line.as_ref()
|
||||||
.char_indices()
|
.char_indices()
|
||||||
.filter(|&(_, c)| c == '#')
|
.filter(|&(_, c)| c == '#')
|
||||||
.map(move |(col, _)| (row as isize, col as isize))
|
.map(move |(col, _)| Loc {
|
||||||
|
row: row as isize,
|
||||||
|
col: col as isize,
|
||||||
|
})
|
||||||
)
|
)
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
@ -41,21 +169,27 @@ mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
static DATA: &[&str] = &[
|
static DATA: &[&str] = &[
|
||||||
".....",
|
"..............",
|
||||||
"..##.",
|
"..............",
|
||||||
"..#..",
|
".......#......",
|
||||||
".....",
|
".....###.#....",
|
||||||
"..##.",
|
"...#...#.#....",
|
||||||
".....",
|
"....#...##....",
|
||||||
|
"...#.###......",
|
||||||
|
"...##.#.##....",
|
||||||
|
"....#..#......",
|
||||||
|
"..............",
|
||||||
|
"..............",
|
||||||
|
"..............",
|
||||||
];
|
];
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn part1() {
|
fn part1() {
|
||||||
assert_eq!(1, solve1(&parse_data(DATA)));
|
assert_eq!(110, solve1(&parse_data(DATA)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn part2() {
|
fn part2() {
|
||||||
assert_eq!(2, solve2(&parse_data(DATA)));
|
assert_eq!(20, solve2(&parse_data(DATA)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue