Skip to content

Commit d9c1121

Browse files
committed
Add day 23
1 parent eb3b18e commit d9c1121

File tree

5 files changed

+312
-0
lines changed

5 files changed

+312
-0
lines changed

day23_input.txt

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
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+
...#.#.#.###..####..#......##.##.###..##..#####..#.##.#.#.##.#######..

day23a/Cargo.toml

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[package]
2+
name = "day23a"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]

day23a/src/main.rs

+121
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
use std::io::Read;
2+
3+
#[derive(Debug, Clone, Copy, PartialEq)]
4+
enum Tile {
5+
Air,
6+
Elf,
7+
Proposal,
8+
Contested,
9+
}
10+
11+
fn main() {
12+
let mut input = String::new();
13+
std::io::stdin().read_to_string(&mut input).unwrap();
14+
15+
const ROUNDS: usize = 10;
16+
let mut elves: Vec<_> = input.lines().enumerate().flat_map(|(y, row)| {
17+
row.chars().enumerate().filter_map(move |(x, c)| {
18+
if c == '#' {
19+
Some(([x + ROUNDS, y + ROUNDS], None))
20+
} else {
21+
None
22+
}
23+
})
24+
}).collect();
25+
26+
let mut sizes = [0; 2];
27+
for (elf, _) in &elves {
28+
for (&coord, size) in elf.iter().zip(&mut sizes) {
29+
*size = std::cmp::max(*size, coord + ROUNDS + 1);
30+
}
31+
}
32+
let sizes = sizes;
33+
34+
let mut map = vec![Tile::Air; sizes.iter().product()];
35+
36+
let pos_to_index = |pos: [usize; 2]| {
37+
pos[0] * sizes[1] + pos[1]
38+
};
39+
40+
for &(elf, _) in &elves {
41+
map[pos_to_index(elf)] = Tile::Elf;
42+
}
43+
44+
let considerations = [
45+
([1, 0], [[0, 0], [1, 0], [2, 0]]),
46+
([1, 2], [[0, 2], [1, 2], [2, 2]]),
47+
([0, 1], [[0, 0], [0, 1], [0, 2]]),
48+
([2, 1], [[2, 0], [2, 1], [2, 2]]),
49+
];
50+
51+
let pos_d_to_index = |pos: [usize; 2], delta: [usize; 2]| {
52+
(pos[0] + delta[0] - 1) * sizes[1] + pos[1] + delta[1] - 1
53+
};
54+
55+
for round in 0..ROUNDS {
56+
for (elf, proposed_pos) in &mut elves {
57+
if [
58+
[0, 0],
59+
[1, 0],
60+
[2, 0],
61+
[0, 1],
62+
[2, 1],
63+
[0, 2],
64+
[1, 2],
65+
[2, 2],
66+
].into_iter().any(|d| {
67+
map[pos_d_to_index(*elf, d)] == Tile::Elf
68+
}) {
69+
if let Some(proposal) = (0..4).find_map(|i| {
70+
let (proposal, adjacent) = &considerations[(round + i) % considerations.len()];
71+
if !adjacent.iter().any(|&d| map[pos_d_to_index(*elf, d)] == Tile::Elf) {
72+
Some(*proposal)
73+
} else {
74+
None
75+
}
76+
}) {
77+
let new_index = pos_d_to_index(*elf, proposal);
78+
*proposed_pos = Some([elf[0] + proposal[0] - 1, elf[1] + proposal[1] - 1]);
79+
80+
match &mut map[new_index] {
81+
t @ Tile::Air => { *t = Tile::Proposal }
82+
t @ Tile::Proposal => { *t = Tile::Contested }
83+
Tile::Contested => {}
84+
Tile::Elf => panic!(),
85+
}
86+
}
87+
}
88+
}
89+
90+
for (elf, proposal) in &mut elves {
91+
if let &mut Some(proposed_pos) = proposal {
92+
match &mut map[pos_to_index(proposed_pos)] {
93+
t @ (Tile::Contested | Tile::Air) => {
94+
*t = Tile::Air;
95+
}
96+
97+
t @ Tile::Proposal => {
98+
*t = Tile::Elf;
99+
map[pos_to_index(*elf)] = Tile::Air;
100+
*elf = proposed_pos;
101+
}
102+
103+
Tile::Elf => panic!(),
104+
}
105+
106+
*proposal = None;
107+
}
108+
}
109+
}
110+
111+
let mut min = [usize::MAX; 2];
112+
let mut max = [usize::MIN; 2];
113+
for (elf, _) in &elves {
114+
for ((&coord, min), max) in elf.iter().zip(&mut min).zip(&mut max) {
115+
*min = std::cmp::min(*min, coord);
116+
*max = std::cmp::max(*max, coord);
117+
}
118+
}
119+
120+
println!("{}", (max[0] - min[0] + 1) * (max[1] - min[1] + 1) - elves.len());
121+
}

day23b/Cargo.toml

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[package]
2+
name = "day23b"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]

day23b/src/main.rs

+105
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
use core::panic;
2+
use std::collections::HashMap;
3+
use std::io::Read;
4+
5+
#[derive(Debug, Clone, Copy, PartialEq)]
6+
enum Tile {
7+
Air,
8+
Elf,
9+
Proposal,
10+
Contested,
11+
}
12+
13+
fn add_pos(pos: [i16; 2], delta: [i16; 2]) -> [i16; 2] {
14+
[pos[0] + delta[0], pos[1] + delta[1]]
15+
}
16+
17+
fn main() {
18+
let mut input = String::new();
19+
std::io::stdin().read_to_string(&mut input).unwrap();
20+
21+
let mut elves: Vec<_> = input.lines().enumerate().flat_map(|(y, row)| {
22+
row.chars().enumerate().filter_map(move |(x, c)| {
23+
if c == '#' {
24+
Some(([x as i16, y as i16], None))
25+
} else {
26+
None
27+
}
28+
})
29+
}).collect();
30+
31+
let mut map = HashMap::new();
32+
33+
for &(elf, _) in &elves {
34+
map.insert(elf, Tile::Elf);
35+
}
36+
37+
let considerations = [
38+
([0, -1], [[-1, -1], [0, -1], [1, -1]]),
39+
([0, 1], [[-1, 1], [0, 1], [1, 1]]),
40+
([-1, 0], [[-1, -1], [-1, 0], [-1, 1]]),
41+
([1, 0], [[1, -1], [1, 0], [1, 1]]),
42+
];
43+
44+
for round in 0.. {
45+
for (elf, proposed_pos) in &mut elves {
46+
if [
47+
[-1, -1],
48+
[0, -1],
49+
[1, -1],
50+
[-1, 0],
51+
[1, 0],
52+
[-1, 1],
53+
[0, 1],
54+
[1, 1],
55+
].into_iter().any(|d| {
56+
map.get(&add_pos(*elf, d)) == Some(&Tile::Elf)
57+
}) {
58+
if let Some(proposal) = (0..4).find_map(|i| {
59+
let (proposal, adjacent) = &considerations[(round + i) % considerations.len()];
60+
if !adjacent.iter().any(|&d| map.get(&add_pos(*elf, d)) == Some(&Tile::Elf)) {
61+
Some(*proposal)
62+
} else {
63+
None
64+
}
65+
}) {
66+
let new_pos = add_pos(*elf, proposal);
67+
*proposed_pos = Some(new_pos);
68+
69+
match map.entry(new_pos).or_insert(Tile::Air) {
70+
t @ Tile::Air => { *t = Tile::Proposal; }
71+
t @ Tile::Proposal => { *t = Tile::Contested; }
72+
Tile::Contested => {}
73+
Tile::Elf => panic!(),
74+
}
75+
}
76+
}
77+
}
78+
79+
let mut moved = false;
80+
81+
for (elf, proposal) in &mut elves {
82+
if let &mut Some(proposed_pos) = proposal {
83+
match map.get_mut(&proposed_pos) {
84+
Some(Tile::Air) => {}
85+
Some(t @ Tile::Contested) => { *t = Tile::Air; }
86+
Some(t @ Tile::Proposal) => {
87+
*t = Tile::Elf;
88+
map.insert(*elf, Tile::Air);
89+
*elf = proposed_pos;
90+
moved = true;
91+
92+
}
93+
None | Some(Tile::Elf) => panic!(),
94+
}
95+
96+
*proposal = None;
97+
}
98+
}
99+
100+
if !moved {
101+
println!("{}", round + 1);
102+
break;
103+
}
104+
}
105+
}

0 commit comments

Comments
 (0)