Advent of Code 2022 - Day 18: Boiling Boulders Solution

Flooding with breadth-first search

Part 1

Reject sides that are next to other cubes

Implementation

1const fs = require("fs")
2
3const readData = () => {
4 const data = fs
5 .readFileSync("./input", "utf-8")
6 .split(/\r?\n/)
7 .map(line => [...line.split(",").map(Number)])
8
9 const set = new Set(data.map(String))
10
11 return { data, set }
12}
13
14const main = () => {
15 const { data, set } = readData()
16
17 const dirs = [
18 [-1, 0, 0],
19 [1, 0, 0],
20 [0, -1, 0],
21 [0, 1, 0],
22 [0, 0, -1],
23 [0, 0, 1],
24 ]
25
26 const SIDES_OF_A_CUBE = 6
27
28 const res = data.reduce(
29 (acc, [x, y, z]) =>
30 acc +
31 (SIDES_OF_A_CUBE -
32 dirs
33 .map(([dx, dy, dz]) => String([x + dx, y + dy, z + dz]))
34 .filter(pos => set.has(pos)).length),
35 0
36 )
37
38 console.log(res)
39}
40
41main()

Part 2

Traversal by flooding all cubes (in defined bound (range))

Whenever an adjacent cube is a lava cube, it means we face one side of the lava cube

For better visualization, ignore one dimension

1. . . . .
2. . L . .
3. L x L .
4. * L . .
5. . . . .
6
7at cube *, we face 2 sides of lava cube
8x here is cube of air, which could never be reached

Implementation

1const fs = require("fs")
2
3const readData = () => {
4 const data = fs
5 .readFileSync("./input", "utf-8")
6 .split(/\r?\n/)
7 .map(line => [...line.split(",").map(Number)])
8
9 const set = new Set(data.map(String))
10
11 return { data, set }
12}
13
14const main = () => {
15 const { data: lavaCubes, set: lavaCubesSet } = readData()
16
17 const dirs = [
18 [-1, 0, 0],
19 [1, 0, 0],
20 [0, -1, 0],
21 [0, 1, 0],
22 [0, 0, -1],
23 [0, 0, 1],
24 ]
25
26 const isInRange = (value, range) => range[0] <= value && value <= range[1]
27
28 const [xRange, yRange, zRange] = Array.from({ length: 3 }, (_, i) =>
29 lavaCubes.map(coord => coord[i])
30 ).map(values => [Math.min(...values) - 1, Math.max(...values) + 1])
31
32 let res = 0
33 let queue = [[xRange[0], yRange[0], zRange[0]]]
34 let visited = new Set()
35
36 while (queue.length) {
37 const currentCube = queue.shift()
38
39 if (visited.has(String(currentCube))) continue
40
41 visited.add(String(currentCube))
42
43 const [x, y, z] = currentCube
44
45 const adjacentCubes = dirs
46 .map(([dx, dy, dz]) => [x + dx, y + dy, z + dz])
47 .filter(
48 ([x, y, z]) =>
49 isInRange(x, xRange) && isInRange(y, yRange) && isInRange(z, zRange)
50 )
51
52 for (const adjacentCube of adjacentCubes) {
53 if (lavaCubesSet.has(String(adjacentCube))) {
54 res++
55 } else {
56 queue.push(adjacentCube)
57 }
58 }
59 }
60
61 console.log(res)
62}
63
64main()

References

Original problem

Flood fill (Wikipedia)

Comments

Loading comments...

Tags

adventofcode

matrix

hash table

bfs

Next Post

Advent of Code 2022 - Day 20: Grove Positioning System

Handling indexes with care

HoningJS

Search Posts