Skip to content

Commit 512dd4c

Browse files
committed
Day 22 go
1 parent 931fdac commit 512dd4c

File tree

1 file changed

+134
-0
lines changed

1 file changed

+134
-0
lines changed

2021/go/d22/main.go

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
package main
2+
3+
import (
4+
"aoc2021/util"
5+
"fmt"
6+
)
7+
8+
type Range struct {
9+
start, end int
10+
}
11+
12+
type Cube struct {
13+
on bool
14+
x, y, z Range
15+
}
16+
17+
// Advent of Code (AOC) 2021 Day 22 Reactor Reboot
18+
func main() {
19+
steps := []Cube{}
20+
util.ReadFile("../input/22a.txt", func(line string) {
21+
var x1, x2, y1, y2, z1, z2 int
22+
var onStr string
23+
fmt.Sscanf(line, "%s x=%d..%d,y=%d..%d,z=%d..%d", &onStr, &x1, &x2, &y1, &y2, &z1, &z2)
24+
on := false
25+
if onStr == "on" {
26+
on = true
27+
}
28+
steps = append(steps, Cube{on, Range{x1, x2}, Range{y1, y2}, Range{z1, z2}})
29+
})
30+
31+
p1steps := []Cube{}
32+
for _, s := range steps {
33+
if _, ok := s.intersect(Cube{true, Range{-50, 50}, Range{-50, 50}, Range{-50, 50}}); ok {
34+
p1steps = append(p1steps, s)
35+
}
36+
}
37+
38+
fmt.Printf("part 1: %v\n", reboot(p1steps))
39+
40+
fmt.Printf("part 2: %v\n", reboot(steps))
41+
}
42+
43+
func reboot(steps []Cube) int64 {
44+
result := []Cube{}
45+
for _, step := range steps { // do each step
46+
newResult := []Cube{} // for each step, build the result
47+
for _, existing := range result { // apply each existing result
48+
newResult = append(newResult, existing.subtract(step)...) // by subtractint the newest step from the result
49+
}
50+
newResult = append(newResult, step) // finally add the current step to the result
51+
result = newResult
52+
}
53+
var sum int64 = 0
54+
for _, c := range result {
55+
if c.on {
56+
sum += c.size()
57+
}
58+
}
59+
return sum
60+
}
61+
62+
// subtract cube from another returning the subtract result as new cubes
63+
func (a Cube) subtract(b Cube) []Cube {
64+
i, ok := a.intersect(b)
65+
if !ok {
66+
return []Cube{a}
67+
}
68+
xp := a.x.split(b.x)
69+
yp := a.y.split(b.y)
70+
zp := a.z.split(b.z)
71+
72+
res := []Cube{}
73+
for _, x := range xp {
74+
for _, y := range yp {
75+
for _, z := range zp {
76+
if x != i.x || y != i.y || z != i.z {
77+
res = append(res, Cube{a.on, x, y, z})
78+
}
79+
}
80+
81+
}
82+
}
83+
return res
84+
}
85+
86+
func (a Cube) intersect(b Cube) (Cube, bool) {
87+
i := Cube{x: a.x.intersect(b.x), y: a.y.intersect(b.y), z: a.z.intersect(b.z)}
88+
return i, i.x.size() > 0 && i.y.size() > 0 && i.z.size() > 0
89+
}
90+
91+
func (a Range) split(b Range) []Range {
92+
res := []Range{}
93+
r1 := Range{a.start, min(b.start-1, a.end)}
94+
r2 := Range{max(a.start, b.start), min(a.end, b.end)}
95+
r3 := Range{max(b.end+1, a.start), a.end}
96+
if r1.size() > 0 {
97+
res = append(res, r1)
98+
}
99+
if r2.size() > 0 {
100+
res = append(res, r2)
101+
}
102+
if r3.size() > 0 {
103+
res = append(res, r3)
104+
}
105+
return res
106+
}
107+
108+
func (a Range) intersect(b Range) Range {
109+
return Range{max(a.start, b.start), min(a.end, b.end)}
110+
}
111+
112+
func (r Range) size() int {
113+
return r.end - r.start + 1
114+
}
115+
116+
func (c Cube) size() int64 {
117+
return int64(c.x.size()) * int64(c.y.size()) * int64(c.z.size())
118+
}
119+
120+
func min(a int, b int) int {
121+
if a < b {
122+
return a
123+
} else {
124+
return b
125+
}
126+
}
127+
128+
func max(a int, b int) int {
129+
if a > b {
130+
return a
131+
} else {
132+
return b
133+
}
134+
}

0 commit comments

Comments
 (0)