2021 Day 22 Complete!
This commit is contained in:
179
2021/day22/main.go
Normal file
179
2021/day22/main.go
Normal file
@@ -0,0 +1,179 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
h "git.bullercodeworks.com/brian/adventofcode/helpers"
|
||||
)
|
||||
|
||||
var steps []cuboid
|
||||
|
||||
func main() {
|
||||
inp := h.StdinToStringSlice()
|
||||
for i := range inp {
|
||||
pts := strings.Split(inp[i], " ")
|
||||
c := strings.Split(pts[1], ",")
|
||||
steps = append(steps, NewCuboid(
|
||||
pts[0] == "on",
|
||||
c[0][2:],
|
||||
c[1][2:],
|
||||
c[2][2:],
|
||||
))
|
||||
}
|
||||
m := c3dMap{
|
||||
Field: make(map[h.Coordinate3d]bool),
|
||||
blfX: -50, trbX: 50,
|
||||
blfY: -50, trbY: 50,
|
||||
blfZ: -50, trbZ: 50,
|
||||
}
|
||||
initialize(&m)
|
||||
reboot()
|
||||
}
|
||||
|
||||
func initialize(m *c3dMap) {
|
||||
fmt.Println("# Part 1")
|
||||
for i := range steps {
|
||||
m.doInitialize(steps[i])
|
||||
}
|
||||
fmt.Printf("After initialization, %d bits are on.\n", m.count(true))
|
||||
}
|
||||
|
||||
func reboot() {
|
||||
fmt.Println("# Part 2")
|
||||
var cuboids []cuboid
|
||||
var volume int64
|
||||
for _, s1 := range steps {
|
||||
adds := make([]cuboid, 0)
|
||||
if s1.val {
|
||||
adds = append(adds, s1)
|
||||
}
|
||||
for _, s2 := range cuboids {
|
||||
if i := s1.intersect(s2, !s2.val); i.valid() {
|
||||
adds = append(adds, i)
|
||||
}
|
||||
}
|
||||
cuboids = append(cuboids, adds...)
|
||||
}
|
||||
for _, c := range cuboids {
|
||||
if c.val {
|
||||
volume += c.volume()
|
||||
} else {
|
||||
volume -= c.volume()
|
||||
}
|
||||
}
|
||||
fmt.Printf("After reboot, %d bits are on.\n", volume)
|
||||
}
|
||||
|
||||
type cuboid struct {
|
||||
val bool
|
||||
x1, x2 int
|
||||
y1, y2 int
|
||||
z1, z2 int
|
||||
}
|
||||
|
||||
func NewCuboid(val bool, x, y, z string) cuboid {
|
||||
s := cuboid{val: val}
|
||||
fmt.Sscanf(x, "%d..%d", &s.x1, &s.x2)
|
||||
fmt.Sscanf(y, "%d..%d", &s.y1, &s.y2)
|
||||
fmt.Sscanf(z, "%d..%d", &s.z1, &s.z2)
|
||||
return s
|
||||
}
|
||||
|
||||
func (s cuboid) volume() int64 {
|
||||
return int64((h.Abs(s.x2-s.x1) + 1) * (h.Abs(s.y2-s.y1) + 1) * (h.Abs(s.z2-s.z1) + 1))
|
||||
}
|
||||
func (s cuboid) valid() bool {
|
||||
return s.x1 <= s.x2 && s.y1 <= s.y2 && s.z1 <= s.z2
|
||||
}
|
||||
func (s cuboid) intersect(t cuboid, val bool) cuboid {
|
||||
return cuboid{
|
||||
val: val,
|
||||
x1: h.Max(s.x1, t.x1),
|
||||
x2: h.Min(s.x2, t.x2),
|
||||
y1: h.Max(s.y1, t.y1),
|
||||
y2: h.Min(s.y2, t.y2),
|
||||
z1: h.Max(s.z1, t.z1),
|
||||
z2: h.Min(s.z2, t.z2),
|
||||
}
|
||||
}
|
||||
func (s cuboid) String() string {
|
||||
return fmt.Sprintf("{%v; x:%d..%d, y:%d..%d, z:%d..%d}", s.val, s.x1, s.x2, s.y1, s.y2, s.z1, s.z2)
|
||||
}
|
||||
|
||||
// Ended up not even using this for part 2
|
||||
type c3dMap struct {
|
||||
Field map[h.Coordinate3d]bool
|
||||
blfX, trbX int
|
||||
blfY, trbY int
|
||||
blfZ, trbZ int
|
||||
}
|
||||
|
||||
func (c *c3dMap) count(v bool) int {
|
||||
var ret int
|
||||
for x := c.blfX; x <= c.trbX; x++ {
|
||||
for y := c.blfY; y <= c.trbY; y++ {
|
||||
for z := c.blfZ; z <= c.trbZ; z++ {
|
||||
if c.Field[h.Coordinate3d{X: x, Y: y, Z: z}] == v {
|
||||
ret++
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (c *c3dMap) doInitialize(s cuboid) {
|
||||
if !c.inRange(s) {
|
||||
return
|
||||
}
|
||||
c.do(s)
|
||||
}
|
||||
|
||||
func (c *c3dMap) do(s cuboid) {
|
||||
for x := s.x1; x <= s.x2; x++ {
|
||||
if x < c.blfX || x > c.trbX {
|
||||
continue
|
||||
}
|
||||
for y := s.y1; y <= s.y2; y++ {
|
||||
if y < c.blfY || x > c.trbY {
|
||||
continue
|
||||
}
|
||||
for z := s.z1; z <= s.z2; z++ {
|
||||
if z < c.blfZ || x > c.trbZ {
|
||||
continue
|
||||
}
|
||||
c.Field[h.Coordinate3d{X: x, Y: y, Z: z}] = s.val
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *c3dMap) inRange(s cuboid) bool {
|
||||
if s.x2 < c.blfX {
|
||||
return false
|
||||
}
|
||||
if s.x1 > c.trbX {
|
||||
return false
|
||||
}
|
||||
if s.y2 < c.blfY {
|
||||
return false
|
||||
}
|
||||
if s.y1 > c.trbY {
|
||||
return false
|
||||
}
|
||||
if s.z2 < c.blfZ {
|
||||
return false
|
||||
}
|
||||
if s.z1 > c.trbZ {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (c c3dMap) Meta() string {
|
||||
return fmt.Sprintf(
|
||||
"{x: %d..%d, y: %d..%d, z: %d..%d}",
|
||||
c.blfX, c.trbX, c.blfY, c.trbY, c.blfZ, c.trbZ,
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user