135 lines
2.3 KiB
Go
135 lines
2.3 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"os"
|
|
"strconv"
|
|
"time"
|
|
)
|
|
|
|
func mustAtoi(line string) int {
|
|
i, _ := strconv.Atoi(line)
|
|
return i
|
|
}
|
|
|
|
func main() {
|
|
start := time.Now()
|
|
partOne()
|
|
duration := time.Since(start)
|
|
partTwo()
|
|
duration2 := time.Since(start)
|
|
fmt.Printf("p1: %s, p2: %s\n", duration, duration2-duration)
|
|
}
|
|
|
|
func makeScanner(test bool) *bufio.Scanner {
|
|
var f *os.File
|
|
if test {
|
|
f, _ = os.Open("inputs/testinput")
|
|
} else {
|
|
f, _ = os.Open("inputs/input")
|
|
}
|
|
reader := bufio.NewReader(f)
|
|
return bufio.NewScanner(reader)
|
|
}
|
|
|
|
type step struct {
|
|
on bool
|
|
x []int
|
|
y []int
|
|
z []int
|
|
}
|
|
|
|
func ParseInput(line string) step {
|
|
s := step{}
|
|
var state byte
|
|
acc := ""
|
|
for i := 0; i < len(line); i++ {
|
|
switch line[i] {
|
|
case '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-':
|
|
acc += string(line[i])
|
|
case 'f':
|
|
s.on = false
|
|
case 'n':
|
|
s.on = true
|
|
case 'x', 'y', 'z':
|
|
state = line[i]
|
|
case '.', ',':
|
|
if line[i] == '.' {
|
|
i++ // skip second .
|
|
}
|
|
switch state {
|
|
case 'x':
|
|
s.x = append(s.x, mustAtoi(acc))
|
|
case 'y':
|
|
s.y = append(s.y, mustAtoi(acc))
|
|
case 'z':
|
|
s.z = append(s.z, mustAtoi(acc))
|
|
}
|
|
acc = ""
|
|
default: // all other characters do nothing
|
|
}
|
|
}
|
|
s.z = append(s.z, mustAtoi(acc)) // catch last number
|
|
return s
|
|
}
|
|
|
|
type coord struct {
|
|
x int
|
|
y int
|
|
z int
|
|
}
|
|
|
|
func GenerateCoords(s step) []coord {
|
|
c := []coord{}
|
|
for x := s.x[0]; x <= s.x[1]; x++ {
|
|
for y := s.y[0]; y <= s.y[1]; y++ {
|
|
for z := s.z[0]; z <= s.z[1]; z++ {
|
|
c = append(c, coord{x, y, z})
|
|
}
|
|
}
|
|
}
|
|
return c
|
|
}
|
|
|
|
func partOne() {
|
|
scanner := makeScanner(true)
|
|
|
|
grid := map[coord]struct{}{}
|
|
steps := []step{}
|
|
for scanner.Scan() {
|
|
steps = append(steps, ParseInput(scanner.Text()))
|
|
}
|
|
for _, step := range steps[0:20] {
|
|
for _, coord := range GenerateCoords(step) {
|
|
if step.on {
|
|
grid[coord] = struct{}{}
|
|
} else {
|
|
delete(grid, coord)
|
|
}
|
|
}
|
|
}
|
|
fmt.Println(len(grid))
|
|
}
|
|
|
|
func partTwo() {
|
|
scanner := makeScanner(true)
|
|
|
|
grid := map[coord]struct{}{}
|
|
steps := []step{}
|
|
for scanner.Scan() {
|
|
steps = append(steps, ParseInput(scanner.Text()))
|
|
}
|
|
// this ain't gonna work
|
|
for _, step := range steps {
|
|
for _, coord := range GenerateCoords(step) {
|
|
if step.on {
|
|
grid[coord] = struct{}{}
|
|
} else {
|
|
delete(grid, coord)
|
|
}
|
|
}
|
|
}
|
|
fmt.Println(len(grid))
|
|
}
|