Skip to content

Commit 71b7775

Browse files
committed
Solved day23
1 parent 9b3bb5e commit 71b7775

File tree

3 files changed

+207
-0
lines changed

3 files changed

+207
-0
lines changed

2022/input/day23.txt

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
.#.##.#...###.#.#.#.#.#....##....#...##...##..#.##..#..#.#.#.###..#....
2+
.....#.#..####.......#.###.....##.#..#.###.#.#..##.#.#.#.#..##.#.######
3+
#.####.##..####.#####.#.##.#..##.#.#.###.######.#.#.##..#####.#.##..##.
4+
#..#.####...#..##...#.#####.######.#...#....##..##..#......##.#####..##
5+
###..#.##..#########...#..####.#.#..##..#.#.#..###..##.###...##.#.#.#..
6+
..#..##.##.###..###.###...#.##..##.#####..#.###.....##...##......##.#..
7+
.###.#..#.#..#..#.##..#...##.#...#...##...##.####....#....#####..####.#
8+
..#####...#..###...#..#.#.#.#..#....#.##.#.#....#.#.#.#.....#.#...###..
9+
.#########.#...###.######..####.#..##..##.##......#..####....##.#....#.
10+
###.#.#....#..#.###..#....##...#..#.##.....#####...##.##...###......#..
11+
.##.##.###.##.###..#..#..##.##.####...#..#.....##..####.##.##...#.##..#
12+
..#..##.#.#...##.#.####.#.#####.########....##.###..#......##.#.####.##
13+
..######...#.#.#####.##...####...##...######.####..##.####...#####.##..
14+
########....##.#.#.#.....#.#.##.#.#...#.#.##..#..#....#...##.##..##..#.
15+
########..#..#.##.##.######...##.##.#..#.###.#..#.#...###...#.##.#####.
16+
#.##..#.##.##..###.##..########.#...###.#.#.###...####..#######.###...#
17+
.###.#.#######.#..#.#.#..#...##..#...##.######..###...#.#.#.#.###.#.###
18+
..###.#..###...#....#..###...##..###.#.#.#.#..##.....##...####..####..#
19+
..####..#..#...#####.#.#.......#.#####.###.##.#..#.#.......#.#.#.##.##.
20+
..##...####.#..###.##..#########.....#....#.#########.#.#...##.##.#....
21+
###..###.#...#...##.##..###..#####..#...#####.##..#.#.###.#.###..###..#
22+
...##...#...##..####.##.#.#..##.###.########.#..#..##.###.#.##.#.#....#
23+
...##.###.######..#.###.####.###..#..#.#....#.##.#.#.##..#..##.#.#.####
24+
######.####...#.....#.#..#..##.#...##.......##.#...######.......##..###
25+
.##..#...##..##.####.###.#.####....####...###.##..###.#.#####.##.......
26+
.##.#.###...#.###..###....#..###...##.#.###.#..###...##.....#..##.###..
27+
.##.#......#.#....#......#.##....###........##..####....#.#..#...#.....
28+
##..#..##..#...#.####..#.##..#####.#.##....##.#####.....###.#...#.###..
29+
#...#..#.#..####.#.#..##.###...##..##...#......#.......##....#..##..#.#
30+
.#..###..##.###......##..####..#.####.#........##.##.#..##.##..#.##..#.
31+
#######.#.#.###.##..##..##.####......#....#.#.#.##.#.#.##.#.###.##.###.
32+
#....#...#.#....###....#...#.#.....#...#.#####.#.......###.#.#..##..##.
33+
.#.#####..#....####.####..#..#....#....#####.##...#.#..##.#..#.#..#.#.#
34+
..##.#.###..##.##....##..####.#.#.#....#####.###..#####.#.#...#..##...#
35+
...#.##.#.#...#.#...#...##.##..#..###....#.#.#.##...#..####...#..##.#.#
36+
..##.#...#...####.#####..#.##.#.#.#..##.....#.##..##....#.....###..####
37+
#.######.###....######.##..#.#.###.##.###..#..####.#...#.#...#.#.##...#
38+
..#.##.#.#####.#....#.#.#..#.####.#..##.#..####.....#..#...##...####.#.
39+
.#..#.....####.#####.#.#.#.....##.##..##.#.#.#..#.....#....#...#.#..#..
40+
....##.##.#..##.##.###.#.......####.#.###..#..##..###.##....#.#.###....
41+
##.#.#.##.##..###..###.#.##.#..#....#.###..#####..##...###..#.##...##..
42+
##..##.##..##..#.##.##...#.###.#.##########...##.##########...###....#.
43+
.####.#.###.##.#####...###.#..##.####...##.##.#.###...##.######.#.#.###
44+
#..##.#..##........#..#.#######..........###..#..###.###.#.#.###.#..##.
45+
.#..###.#...###.####..#..#..#.#.###.##.#..##...#####.....###.......#..#
46+
#.##.####..###..#......#.##...#..#..#..#.....#.#....##.####..#.###.##.#
47+
.#.###..###.##.###.#.#.##.####.###..#..#..######.###.#...##..#.##..#..#
48+
#.#..#.........#.####..#....#.#....#.#####..##..#..#..#.....###.#..####
49+
.#.#....####.##.##.#...#......#.#.#.....#....#....#.##..#..##.#..##.###
50+
##...#..######........##.#...#####..#.#.#.####..#####.#.#...#.##..###..
51+
.##.####.#.##.##....#.#.#...#.#####..##......#.#.##.#.#.###.#......#..#
52+
############...##.##.#..#.#...#######.#....###....####..#.#######.#...#
53+
#.#.#..####..#.#.#..##......###.###...##.#..##..########.##.###..#..##.
54+
#.#.##.#.####..#.###.###.#.#.##.#....#######..###.#..##.#...#.###.###.#
55+
...#.#.....####....#...#.#.#....#..###..#.#.#.###..##.#..#...#..##..#.#
56+
.##.##...#...####....#....#.#.###..##.##..####.#..#.###.#####..##...#..
57+
...#..#..###..#...#######.#.###.##...#....####.#.#..##.##...#...#...###
58+
....#..#.#.#.##..#.##.#.###...###.....#.#..##.#.##..#.##.###..#.#.###.#
59+
####.#######.#.#.###...##.#..##..#.#...###..#...#.###.###....#...#...##
60+
.###.#.#.#...#....##.####.#....#.....#.#..##.##.##.#.##.#..#.#.......##
61+
#..###.##..###.##...###..#..##.#.#...##..#.#........#.###..######...#.#
62+
..######.###..###.#......#.#.###.####.#...#.#.##.#.......##..#.##....#.
63+
#.###.#.#.###.#.#.##.........##...#....#.###..#...#.#..#.##....#..##..#
64+
.##.#..#.#....#...#..###........#..#..##..##.#...#.###...########.##.##
65+
.##...#.....#.###.##....#.#..#..####.###...##...#..###...##..##.#####..
66+
#######..#.#.#.####.##..#######.#..##.#...###.....###.#..####.#.###.#.#
67+
.##..#...##.....##..###.##..##.###########.####..##.......#...#.###.#..
68+
....##....##.###.####...#..#....##.#.#.#...####.##..#...#.......##..#.#
69+
##..##.##.#..##.#...##.....#.##..#.#.##.##.#...#...#.##..#.#.#.#.#.##..
70+
##..##.##...##..##.###..##.##..########..##......#.#..#..###..#####..#.
71+
.#.##..#..##.######.#.#....##.###..#..#.#...#.#....####.#####.#.#..###.

2022/input/day23_example.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
....#..
2+
..###.#
3+
#...#.#
4+
.#...##
5+
#.###..
6+
##.#.##
7+
.#..#..

2022/src/bin/day23.rs

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
#![feature(test)]
2+
3+
use advent_lib::direction::Direction;
4+
use advent_lib::geometry::{point2, vector2, Vector};
5+
use advent_lib::{
6+
direction::CardinalDirection,
7+
grid::{Grid, Location},
8+
*,
9+
};
10+
use advent_macros::FromRepr;
11+
use fxhash::FxHashMap;
12+
use std::cmp::{max, min};
13+
14+
#[repr(u8)]
15+
#[derive(FromRepr, PartialEq, Copy, Clone, Default)]
16+
enum Ground {
17+
#[default]
18+
Empty = b'.',
19+
Elf = b'#',
20+
}
21+
22+
type Elfs = Grid<Ground>;
23+
24+
fn prepare(grid: Grid<Ground>) -> Elfs {
25+
let mut elfs = Grid::new_empty(grid.width() * 3, grid.height() * 3);
26+
let offset = vector2(grid.width(), grid.height());
27+
for (loc, ground) in grid.entries() {
28+
if let Some(target) = elfs.get_mut(loc + offset) {
29+
*target = *ground;
30+
}
31+
}
32+
elfs
33+
}
34+
35+
const DIRECTIONS: [(Direction, [usize; 3]); 4] = [
36+
(Direction::North, [7, 0, 1]),
37+
(Direction::South, [3, 4, 5]),
38+
(Direction::West, [5, 6, 7]),
39+
(Direction::East, [1, 2, 3]),
40+
];
41+
42+
fn find_possible_move(round: usize, has_elfs: [bool; 8]) -> Option<Direction> {
43+
for ix in 0..4 {
44+
let (dir, ixs) = DIRECTIONS[(round + ix) % 4];
45+
if ixs.iter().all(|&ix| !has_elfs[ix]) {
46+
return Some(dir);
47+
}
48+
}
49+
None
50+
}
51+
52+
fn step(elfs: &mut Elfs, round: usize) -> bool {
53+
let mut proposals = Vec::<(Location, Location)>::with_capacity(elfs.len());
54+
let mut proposal_count = FxHashMap::with_capacity_and_hasher(elfs.len(), Default::default());
55+
elfs.entries().filter(|&(_, g)| g == &Ground::Elf).for_each(|(loc, _)| {
56+
let has_elfs = CardinalDirection::ALL.map(|dir| elfs.get(loc + dir) == Some(&Ground::Elf));
57+
if has_elfs.iter().any(|&has_elf| has_elf) {
58+
if let Some(dir) = find_possible_move(round, has_elfs) {
59+
let target = loc + dir;
60+
proposals.push((loc, target));
61+
*proposal_count.entry(target).or_default() += 1;
62+
}
63+
}
64+
});
65+
66+
let mut some_change = false;
67+
for &(current, target) in proposals.iter() {
68+
if proposal_count.get(&target) == Some(&1) {
69+
if let Some(ground) = elfs.get_mut(current) {
70+
*ground = Ground::Empty
71+
}
72+
if let Some(ground) = elfs.get_mut(target) {
73+
*ground = Ground::Elf
74+
}
75+
some_change = true;
76+
}
77+
}
78+
79+
some_change
80+
}
81+
82+
fn get_range(elfs: &Elfs) -> (Vector<2, i32>, Vector<2, i32>) {
83+
let middle = vector2(elfs.width() / 2, elfs.height() / 2);
84+
elfs.entries().filter(|&(_, ground)| ground == &Ground::Elf).fold(
85+
(middle, middle),
86+
|(low, high), (curr, _)| {
87+
(
88+
vector2(min(low.x(), curr.x()), min(low.y(), curr.y())),
89+
vector2(max(high.x(), curr.x()), max(high.y(), curr.y())),
90+
)
91+
},
92+
)
93+
}
94+
95+
fn empty_fields(elfs: &Elfs) -> i32 {
96+
let (min, max) = get_range(elfs);
97+
let mut count = 0;
98+
for y in min.y()..=max.y() {
99+
for x in min.x()..=max.x() {
100+
if elfs.get(point2(x, y)) == Some(&Ground::Empty) {
101+
count += 1;
102+
}
103+
}
104+
}
105+
count
106+
}
107+
108+
fn calculate_part1(elfs: &Elfs) -> i32 {
109+
let mut elfs = elfs.clone();
110+
for round in 0..10 {
111+
step(&mut elfs, round);
112+
}
113+
empty_fields(&elfs)
114+
}
115+
116+
fn calculate_part2(elfs: &Elfs) -> usize {
117+
let mut elfs = elfs.clone();
118+
for round in 0.. {
119+
let change = step(&mut elfs, round);
120+
if !change {
121+
return round + 1;
122+
}
123+
}
124+
0
125+
}
126+
127+
day_main!(prepare => calculate_part1, calculate_part2);
128+
day_test!(23, example => 110, 20 ; crate::prepare );
129+
day_test!(23 => 3762 ; crate::prepare ); // Part 2 is 997 but takes 5 seconds in test mode

0 commit comments

Comments
 (0)