adventofcode/2017/day22/day22.go

214 lines
3.0 KiB
Go

package main
import (
"bufio"
"fmt"
"log"
"os"
"strconv"
"strings"
)
const (
N = iota
E
S
W
)
const (
ST_CLEAN = iota
ST_WEAK
ST_INFECTED
ST_FLAGGED
ST_ERROR
)
var nodes map[string]int
var cX, cY, cD int
var minX, minY, maxX, maxY int
var tickCount, infectCount int
func main() {
inp := StdinToStrings()
nodes = make(map[string]int)
cX, cY, cD = len(inp)/2, len(inp[0])/2, N
for y := 0; y < len(inp); y++ {
for x := 0; x < len(inp[y]); x++ {
nodes[cs(x, y)] = ST_CLEAN
if inp[y][x] == '#' {
nodes[cs(x, y)] = ST_INFECTED
}
updateMinMax(x, y)
}
}
for i := 0; i < 10000000; i++ {
//ClearScreen()
if part1 {
p1Tick()
} else {
p2Tick()
}
//PrettyPrint()
//PrintStatus()
//time.Sleep(time.Second / 5)
}
}
func p1Tick() {
tickCount++
switch nodes[cs(cX, cY)] {
case ST_INFECTED:
TurnRight()
nodes[cs(cX, cY)] = ST_CLEAN
infectCount++
default:
TurnLeft()
nodes[cs(cX, cY)] = ST_INFECTED
infectCount++
}
cX, cY = getXYInDir()
updateMinMax(cX, cY)
}
func p2Tick() {
tickCount++
switch nodes[cs(cX, cY)] {
case ST_CLEAN:
TurnLeft()
nodes[cs(cX, cY)] = ST_WEAK
case ST_WEAK:
nodes[cs(cX, cY)] = ST_INFECTED
infectCount++
case ST_INFECTED:
TurnRight()
nodes[cs(cX, cY)] = ST_FLAGGED
case ST_FLAGGED:
TurnRight()
TurnRight()
nodes[cs(cX, cY)] = ST_CLEAN
}
cX, cY = getXYInDir()
updateMinMax(cX, cY)
}
func updateMinMax(x, y int) {
if x < minX {
minX = x
}
if x > maxX {
maxX = x
}
if y < minY {
minY = y
}
if y > maxY {
maxY = y
}
}
func PrettyPrint() {
for kY := minY; kY <= maxY; kY++ {
for kX := minX; kX <= maxX; kX++ {
if kX == cX && kY == cY {
fmt.Print("[")
} else {
fmt.Print(" ")
}
switch nodes[cs(kX, kY)] {
case ST_CLEAN:
fmt.Print(".")
case ST_WEAK:
fmt.Print("W")
case ST_INFECTED:
fmt.Print("#")
case ST_FLAGGED:
fmt.Print("F")
}
if kX == cX && kY == cY {
fmt.Print("]")
} else {
fmt.Print(" ")
}
}
fmt.Println()
}
}
func PrintStatus() {
fmt.Println("Ticks:", tickCount)
fmt.Println("Infections:", infectCount)
}
func TurnRight() {
switch cD {
case N:
cD = E
case E:
cD = S
case S:
cD = W
case W:
cD = N
}
}
func TurnLeft() {
switch cD {
case N:
cD = W
case E:
cD = N
case S:
cD = E
case W:
cD = S
}
}
func getXYInDir() (int, int) {
switch cD {
case N:
return cX, cY - 1
case E:
return cX + 1, cY
case S:
return cX, cY + 1
case W:
return cX - 1, cY
}
return cX, cY
}
func cs(x, y int) string {
return fmt.Sprintf("%d;%d", x, y)
}
func sc(key string) (int, int) {
pts := strings.Split(key, ";")
return Atoi(pts[0]), Atoi(pts[1])
}
func Atoi(i string) int {
var ret int
var err error
if ret, err = strconv.Atoi(i); err != nil {
log.Fatal("Invalid Atoi")
}
return ret
}
func ClearScreen() {
fmt.Println("\033[H\033[2J")
}
func StdinToStrings() []string {
var input []string
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
input = append(input, scanner.Text())
}
return input
}