Day 18
This commit is contained in:
139
day18/common/lava.go
Normal file
139
day18/common/lava.go
Normal file
@@ -0,0 +1,139 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
|
||||
type Cube struct {
|
||||
x, y, z int
|
||||
}
|
||||
|
||||
|
||||
type Grid struct {
|
||||
cubes map[Cube]struct{}
|
||||
outsideCubes map[Cube]struct{}
|
||||
exposedFaces int
|
||||
insideFaces int
|
||||
minX, maxX, minY, maxY, minZ, maxZ int
|
||||
}
|
||||
|
||||
func (grid *Grid) AddCube(x, y, z int) {
|
||||
grid.cubes[Cube{x, y, z}] = struct{}{}
|
||||
grid.exposedFaces += 6
|
||||
grid.exposedFaces -= 2 * grid.GetCoveredFaces(x, y, z)
|
||||
|
||||
if x <= grid.minX {
|
||||
grid.minX = x - 1
|
||||
}
|
||||
if x >= grid.maxX {
|
||||
grid.maxX = x + 1
|
||||
}
|
||||
if y <= grid.minY {
|
||||
grid.minY = y - 1
|
||||
}
|
||||
if y >= grid.maxY {
|
||||
grid.maxY = y + 1
|
||||
}
|
||||
if z <= grid.minZ {
|
||||
grid.minZ = z - 1
|
||||
}
|
||||
if z >= grid.maxZ {
|
||||
grid.maxZ = z + 1
|
||||
}
|
||||
}
|
||||
|
||||
func (grid *Grid) PropagateWater(cube Cube, visited map[Cube]struct{}) {
|
||||
grid.outsideCubes[cube] = struct{}{}
|
||||
|
||||
visited2 := make(map[Cube]struct{})
|
||||
visited2[cube] = struct{}{}
|
||||
|
||||
cubes := []Cube{{cube.x-1, cube.y, cube.z}, {cube.x+1, cube.y, cube.z},
|
||||
{cube.x, cube.y-1, cube.z}, {cube.x, cube.y+1, cube.z},
|
||||
{cube.x, cube.y, cube.z-1}, {cube.x, cube.y, cube.z+1}}
|
||||
for _, cube2 := range cubes {
|
||||
if _, ok := grid.cubes[cube2]; !ok && cube2.x >= grid.minX && cube2.x <= grid.maxX &&
|
||||
cube2.y >= grid.minY && cube2.y <= grid.maxY && cube2.z >= grid.minZ && cube2.z <= grid.maxZ {
|
||||
if _, ok := visited[cube2]; !ok {
|
||||
if _, ok := grid.outsideCubes[cube2]; !ok {
|
||||
for c := range(visited) {
|
||||
visited2[c] = visited[c]
|
||||
}
|
||||
grid.PropagateWater(cube2, visited2)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (grid *Grid) GetInsideFaces(cube Cube) int {
|
||||
cubes := []Cube{{cube.x-1, cube.y, cube.z}, {cube.x+1, cube.y, cube.z},
|
||||
{cube.x, cube.y-1, cube.z}, {cube.x, cube.y+1, cube.z},
|
||||
{cube.x, cube.y, cube.z-1}, {cube.x, cube.y, cube.z+1}}
|
||||
nFaces := 0
|
||||
for _, cube := range cubes {
|
||||
if _, ok := grid.cubes[cube]; !ok {
|
||||
if _, ok := grid.outsideCubes[cube]; !ok {
|
||||
nFaces++
|
||||
}
|
||||
}
|
||||
}
|
||||
return nFaces
|
||||
}
|
||||
|
||||
func (grid *Grid) GetCoveredFaces(x, y, z int) int {
|
||||
coveredFaces := 0
|
||||
if _, found := grid.cubes[Cube{x-1, y, z}]; found {
|
||||
coveredFaces += 1
|
||||
}
|
||||
if _, found := grid.cubes[Cube{x+1, y, z}]; found {
|
||||
coveredFaces += 1
|
||||
}
|
||||
if _, found := grid.cubes[Cube{x, y-1, z}]; found {
|
||||
coveredFaces += 1
|
||||
}
|
||||
if _, found := grid.cubes[Cube{x, y+1, z}]; found {
|
||||
coveredFaces += 1
|
||||
}
|
||||
if _, found := grid.cubes[Cube{x, y, z-1}]; found {
|
||||
coveredFaces += 1
|
||||
}
|
||||
if _, found := grid.cubes[Cube{x, y, z+1}]; found {
|
||||
coveredFaces += 1
|
||||
}
|
||||
return coveredFaces
|
||||
}
|
||||
|
||||
func (grid *Grid) GetTotalExposedFaces() int {
|
||||
return grid.exposedFaces
|
||||
}
|
||||
|
||||
func (grid *Grid) GetTotalOutsideArea() int {
|
||||
return grid.exposedFaces - grid.insideFaces
|
||||
}
|
||||
|
||||
|
||||
func Parse(scanner bufio.Scanner) Grid {
|
||||
grid := Grid{make(map[Cube]struct{}), make(map[Cube]struct{}), 0, 0,
|
||||
math.MaxInt32, math.MinInt32, math.MaxInt32, math.MinInt32, math.MaxInt32, math.MinInt32}
|
||||
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
splittedLine := strings.Split(line, ",")
|
||||
x, _ := strconv.Atoi(splittedLine[0])
|
||||
y, _ := strconv.Atoi(splittedLine[1])
|
||||
z, _ := strconv.Atoi(splittedLine[2])
|
||||
grid.AddCube(x, y, z)
|
||||
}
|
||||
|
||||
grid.PropagateWater(Cube{grid.minX, grid.minY, grid.minZ}, make(map[Cube]struct{}))
|
||||
for cube := range(grid.cubes) {
|
||||
grid.insideFaces += grid.GetInsideFaces(cube)
|
||||
}
|
||||
|
||||
return grid
|
||||
}
|
||||
14
day18/ex1/main.go
Normal file
14
day18/ex1/main.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"aoc2022/day18/common"
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
func main() {
|
||||
grid := common.Parse(*bufio.NewScanner(os.Stdin))
|
||||
|
||||
fmt.Println(grid.GetTotalExposedFaces())
|
||||
}
|
||||
14
day18/ex2/main.go
Normal file
14
day18/ex2/main.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"aoc2022/day18/common"
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
func main() {
|
||||
grid := common.Parse(*bufio.NewScanner(os.Stdin))
|
||||
|
||||
fmt.Println(grid.GetTotalOutsideArea())
|
||||
}
|
||||
Reference in New Issue
Block a user