Skip to content

Commit f6928dd

Browse files
committed
day 17
1 parent 0a4f815 commit f6928dd

File tree

6 files changed

+164
-0
lines changed

6 files changed

+164
-0
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,8 @@ Part Two: 48568
6666
--- Day 16: Ticket Translation ---
6767
Part One: 25916
6868
Part Two: 2564529489989
69+
70+
--- Day 17: Conway Cubes ---
71+
Part One: 237
72+
Part Two: 2448
6973
```

inputs/17-example.txt

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

inputs/17-input.txt

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

src/day17.rs

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
use std::collections::HashSet;
2+
3+
fn parse_input(input: &str) -> Vec<Vec<char>> {
4+
input.lines().map(|s| s.chars().collect()).collect()
5+
}
6+
7+
pub fn part_one(input: &str) -> usize {
8+
let grid = parse_input(input);
9+
let h = grid.len();
10+
let w = grid[0].len();
11+
let mut cubes: HashSet<(i32, i32, i32)> = grid
12+
.iter()
13+
.enumerate()
14+
.flat_map(|(y, row)| {
15+
row.iter().enumerate().filter_map(move |(x, &c)| {
16+
if c == '#' {
17+
Some((x as i32, y as i32, 0))
18+
} else {
19+
None
20+
}
21+
})
22+
})
23+
.collect();
24+
25+
fn process_cube(
26+
pos: (i32, i32, i32),
27+
cube: &HashSet<(i32, i32, i32)>,
28+
new_cubes: &mut HashSet<(i32, i32, i32)>,
29+
) {
30+
let neighbors = {
31+
let mut count = 0;
32+
for x in -1..=1 {
33+
for y in -1..=1 {
34+
for z in -1..=1 {
35+
if x == 0 && y == 0 && z == 0 {
36+
continue;
37+
}
38+
if cube.contains(&(pos.0 + x, pos.1 + y, pos.2 + z)) {
39+
count += 1;
40+
}
41+
}
42+
}
43+
}
44+
count
45+
};
46+
if neighbors == 3 || (cube.contains(&pos) && neighbors == 2) {
47+
new_cubes.insert(pos);
48+
}
49+
}
50+
51+
let mut new_cubes = HashSet::new();
52+
for i in 1..=6 {
53+
for x in -i..w as i32 + i {
54+
for y in -i..h as i32 + i {
55+
for z in -i..=i {
56+
process_cube((x, y, z), &cubes, &mut new_cubes);
57+
}
58+
}
59+
}
60+
cubes = new_cubes;
61+
new_cubes = HashSet::new();
62+
}
63+
64+
cubes.len()
65+
}
66+
67+
pub fn part_two(input: &str) -> usize {
68+
let grid = parse_input(input);
69+
let h = grid.len();
70+
let w = grid[0].len();
71+
let mut cubes: HashSet<(i32, i32, i32, i32)> = grid
72+
.iter()
73+
.enumerate()
74+
.flat_map(|(y, row)| {
75+
row.iter().enumerate().filter_map(move |(x, &c)| {
76+
if c == '#' {
77+
Some((x as i32, y as i32, 0, 0))
78+
} else {
79+
None
80+
}
81+
})
82+
})
83+
.collect();
84+
85+
fn process_cube(
86+
pos: (i32, i32, i32, i32),
87+
cube: &HashSet<(i32, i32, i32, i32)>,
88+
new_cubes: &mut HashSet<(i32, i32, i32, i32)>,
89+
) {
90+
let neighbors = {
91+
let mut count = 0;
92+
for x in -1..=1 {
93+
for y in -1..=1 {
94+
for z in -1..=1 {
95+
for w in -1..=1 {
96+
if x == 0 && y == 0 && z == 0 && w == 0 {
97+
continue;
98+
}
99+
if cube.contains(&(
100+
pos.0 + x,
101+
pos.1 + y,
102+
pos.2 + z,
103+
pos.3 + w,
104+
)) {
105+
count += 1;
106+
}
107+
}
108+
}
109+
}
110+
}
111+
count
112+
};
113+
if neighbors == 3 || (cube.contains(&pos) && neighbors == 2) {
114+
new_cubes.insert(pos);
115+
}
116+
}
117+
118+
let mut new_cubes = HashSet::new();
119+
for i in 1..=6 {
120+
for x in -i..w as i32 + i {
121+
for y in -i..h as i32 + i {
122+
for z in -i..=i {
123+
for w in -i..=i {
124+
process_cube((x, y, z, w), &cubes, &mut new_cubes);
125+
}
126+
}
127+
}
128+
}
129+
cubes = new_cubes;
130+
new_cubes = HashSet::new();
131+
}
132+
133+
cubes.len()
134+
}
135+
136+
#[cfg(test)]
137+
mod tests {
138+
use super::*;
139+
use crate::read_example;
140+
141+
#[test]
142+
fn example() {
143+
let input = read_example(17);
144+
assert_eq!(part_one(&input), 112);
145+
assert_eq!(part_two(&input), 848);
146+
}
147+
}

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ pub mod day13;
1616
pub mod day14;
1717
pub mod day15;
1818
pub mod day16;
19+
pub mod day17;
1920

2021
pub fn read_as_string(day: u8, filename: &str) -> String {
2122
let filename = format!("inputs/{:02}-{}.txt", day, filename);

src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ fn main() {
3232
puzzle!(day14, "Docking Data"),
3333
puzzle!(day15, "Rambunctious Recitation"),
3434
puzzle!(day16, "Ticket Translation"),
35+
puzzle!(day17, "Conway Cubes"),
3536
];
3637

3738
let filename = match env::args().find(|a| a == "--example") {

0 commit comments

Comments
 (0)