2019 Day 11 Complete
This commit is contained in:
188
2019/day11/main.go
Normal file
188
2019/day11/main.go
Normal file
@@ -0,0 +1,188 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
intcode "git.bullercodeworks.com/brian/adventofcode/2019/intcode-processor"
|
||||
helpers "git.bullercodeworks.com/brian/adventofcode/helpers"
|
||||
)
|
||||
|
||||
// Pass the program name and the problem part number in parameters
|
||||
// Default: "input", and part 2
|
||||
func main() {
|
||||
progFileName := "input"
|
||||
part := 2
|
||||
if len(os.Args) > 1 {
|
||||
progFileName = os.Args[1]
|
||||
if len(os.Args) == 3 {
|
||||
part = helpers.Atoi(os.Args[2])
|
||||
}
|
||||
}
|
||||
dat, err := ioutil.ReadFile(progFileName)
|
||||
if err != nil {
|
||||
fmt.Println("Error reading program file:", err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
var prog []int
|
||||
stringDat := strings.TrimSpace(string(dat))
|
||||
for _, v := range strings.Split(stringDat, ",") {
|
||||
prog = append(prog, helpers.Atoi(v))
|
||||
}
|
||||
// Pass the program and the problem part to solve:
|
||||
solve(prog, part)
|
||||
}
|
||||
|
||||
func solve(inp []int, pt int) {
|
||||
painter := NewPainter()
|
||||
if pt == 2 {
|
||||
painter.Paint(1)
|
||||
}
|
||||
p := intcode.NewProgram(inp)
|
||||
go func() {
|
||||
for {
|
||||
for !p.NeedsInput() {
|
||||
time.Sleep(1)
|
||||
}
|
||||
p.Input(painter.GetPanelColor())
|
||||
for !p.NeedsOutput() {
|
||||
time.Sleep(1)
|
||||
}
|
||||
painter.Paint(p.Output())
|
||||
for !p.NeedsOutput() {
|
||||
time.Sleep(1)
|
||||
}
|
||||
painter.Turn(p.Output())
|
||||
switch p.State() {
|
||||
case intcode.RET_ERR:
|
||||
panic(p.Error())
|
||||
case intcode.RET_DONE:
|
||||
break
|
||||
}
|
||||
}
|
||||
}()
|
||||
res := p.Run()
|
||||
if res == intcode.RET_DONE {
|
||||
fmt.Println("DONE")
|
||||
} else if res == intcode.RET_ERR {
|
||||
fmt.Println("ERROR")
|
||||
}
|
||||
painter.Print()
|
||||
fmt.Println("Painted Panels:", len(painter.panels))
|
||||
fmt.Println("Paint Used:", painter.paintCount)
|
||||
}
|
||||
|
||||
const (
|
||||
DIR_N = iota
|
||||
DIR_E
|
||||
DIR_S
|
||||
DIR_W
|
||||
)
|
||||
|
||||
type Painter struct {
|
||||
dir int
|
||||
loc helpers.Coordinate
|
||||
panels map[string]int
|
||||
paintCount int
|
||||
minX, minY int
|
||||
maxX, maxY int
|
||||
|
||||
panelMutex *sync.Mutex
|
||||
}
|
||||
|
||||
func NewPainter() *Painter {
|
||||
p := Painter{
|
||||
dir: DIR_N,
|
||||
loc: helpers.Coordinate{X: 0, Y: 0},
|
||||
panels: make(map[string]int),
|
||||
panelMutex: &sync.Mutex{},
|
||||
}
|
||||
return &p
|
||||
}
|
||||
|
||||
func (p *Painter) GetPanelColor() int {
|
||||
if v, ok := p.panels[p.loc.String()]; ok {
|
||||
return v
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (p *Painter) Paint(color int) {
|
||||
p.panelMutex.Lock()
|
||||
p.panels[p.loc.String()] = color
|
||||
p.paintCount++
|
||||
p.panelMutex.Unlock()
|
||||
}
|
||||
|
||||
func (p *Painter) Turn(dir int) {
|
||||
if dir == 0 {
|
||||
p.dir--
|
||||
} else {
|
||||
p.dir++
|
||||
}
|
||||
if p.dir == DIR_W+1 {
|
||||
p.dir = DIR_N
|
||||
} else if p.dir == DIR_N-1 {
|
||||
p.dir = DIR_W
|
||||
}
|
||||
// After turning we move forward
|
||||
switch p.dir {
|
||||
case DIR_N:
|
||||
p.loc.Y--
|
||||
case DIR_E:
|
||||
p.loc.X++
|
||||
case DIR_S:
|
||||
p.loc.Y++
|
||||
case DIR_W:
|
||||
p.loc.X--
|
||||
}
|
||||
if p.loc.X < p.minX {
|
||||
p.minX = p.loc.X
|
||||
}
|
||||
if p.loc.X > p.maxX {
|
||||
p.maxX = p.loc.X
|
||||
}
|
||||
if p.loc.Y < p.minY {
|
||||
p.minY = p.loc.Y
|
||||
}
|
||||
if p.loc.Y > p.maxY {
|
||||
p.maxY = p.loc.Y
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Painter) Print() {
|
||||
for x := p.minX; x <= p.maxX; x++ {
|
||||
for y := p.minY; y <= p.maxY; y++ {
|
||||
c := helpers.Coordinate{x, y}
|
||||
if c.X == p.loc.X && c.Y == p.loc.Y {
|
||||
switch p.dir {
|
||||
case DIR_N:
|
||||
fmt.Print("^")
|
||||
case DIR_E:
|
||||
fmt.Print(">")
|
||||
case DIR_S:
|
||||
fmt.Print("v")
|
||||
case DIR_W:
|
||||
fmt.Print("<")
|
||||
}
|
||||
} else {
|
||||
p.panelMutex.Lock()
|
||||
if v, ok := p.panels[c.String()]; ok {
|
||||
if v == 1 {
|
||||
fmt.Print("#")
|
||||
} else {
|
||||
fmt.Print(".")
|
||||
}
|
||||
} else {
|
||||
fmt.Print(".")
|
||||
}
|
||||
p.panelMutex.Unlock()
|
||||
}
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user