1
0
Fork 0
mirror of https://github.com/Luzifer/aoc2019.git synced 2024-12-22 05:51:16 +00:00

Add solution for Day 11

Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
Knut Ahlers 2019-12-12 18:16:01 +01:00
parent 38c9de6a8a
commit 0602aad44e
Signed by: luzifer
GPG key ID: DC2729FDD34BE99E
4 changed files with 194 additions and 0 deletions

172
day11.go Normal file
View file

@ -0,0 +1,172 @@
package aoc2019
import (
"fmt"
"image"
"image/color"
"image/png"
"io/ioutil"
"math"
"os"
"strings"
"sync"
"github.com/pkg/errors"
)
type day11PaintDirective struct {
X, Y int
Color int64
}
func (d day11PaintDirective) positionKey() string { return fmt.Sprintf("%d:%d", d.X, d.Y) }
func day11ExecutePaintRobot(inFile string, startPanelColor int64) ([]day11PaintDirective, error) {
var (
posX, posY int
direction int // Clock-hand direction
directives = map[string]day11PaintDirective{
"0:0": {X: 0, Y: 0, Color: startPanelColor},
}
)
move := func() {
switch direction {
case 0:
posY -= 1
case 3:
posX += 1
case 6:
posY += 1
case 9:
posX -= 1
default:
panic(errors.Errorf("Invalid direction: %d", direction))
}
}
rotate := func(dir int64) {
var factor int
if dir == 1 {
// turn right
factor = 1
} else {
// turn left
factor = -1
}
direction = direction + factor*3
if direction < 0 {
direction += 12
}
if direction > 11 {
direction -= 12
}
}
// Initialize code
rawCode, err := ioutil.ReadFile(inFile)
if err != nil {
return nil, errors.Wrap(err, "Unable to read intcode")
}
code, err := parseIntcode(strings.TrimSpace(string(rawCode)))
if err != nil {
return nil, errors.Wrap(err, "Unable to parse intcode")
}
// Run program in background
var (
in = make(chan int64, 1)
out = make(chan int64, 2)
outputs []int64
programExit bool
wg = new(sync.WaitGroup)
)
go executeIntcode(code, in, out)
go func() {
for o := range out {
outputs = append(outputs, o)
wg.Done()
}
programExit = true
}()
// Start feeding scan results
for !programExit {
// Get previous directive for current position
var dir = day11PaintDirective{X: posX, Y: posY}
if d, ok := directives[dir.positionKey()]; ok {
dir = d
}
// Feed current color and expect two output
wg.Add(2)
in <- dir.Color
wg.Wait()
// Set current color
dir.Color = outputs[0]
directives[dir.positionKey()] = dir
// Rotate robot
rotate(outputs[1])
// Move
move()
// Reset outputs
outputs = nil
}
var result []day11PaintDirective
for _, v := range directives {
result = append(result, v)
}
return result, nil
}
func solveDay11Part1(inFile string) (int, error) {
dirs, err := day11ExecutePaintRobot(inFile, 0)
return len(dirs), errors.Wrap(err, "Unable to execute robot")
}
func solveDay11Part2(inFile string) error {
dirs, err := day11ExecutePaintRobot(inFile, 1)
if err != nil {
return errors.Wrap(err, "Unable to execute robot")
}
var minX, minY, maxX, maxY = math.MaxInt64, math.MaxInt64, 0, 0
for _, dir := range dirs {
if dir.X < minX {
minX = dir.X
}
if dir.X > maxX {
maxX = dir.X
}
if dir.Y < minY {
minY = dir.Y
}
if dir.Y > maxY {
maxY = dir.Y
}
}
colors := map[int64]color.Color{
0: color.RGBA{0x0, 0x0, 0x0, 0xff},
1: color.RGBA{0xff, 0xff, 0xff, 0xff},
}
img := image.NewRGBA(image.Rect(minX-5, minY-5, maxX+5, maxY+5))
for _, dir := range dirs {
img.Set(dir.X, dir.Y, colors[dir.Color])
}
w, err := os.Create("day11_image.png")
if err != nil {
return errors.Wrap(err, "Unable to open result image file")
}
defer w.Close()
return errors.Wrap(png.Encode(w, img), "Unable to store image")
}

BIN
day11_image.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 B

1
day11_input.txt Normal file
View file

@ -0,0 +1 @@
3,8,1005,8,325,1106,0,11,0,0,0,104,1,104,0,3,8,102,-1,8,10,1001,10,1,10,4,10,1008,8,0,10,4,10,102,1,8,29,1006,0,41,3,8,1002,8,-1,10,101,1,10,10,4,10,1008,8,0,10,4,10,1001,8,0,54,3,8,102,-1,8,10,101,1,10,10,4,10,1008,8,1,10,4,10,102,1,8,76,1,9,11,10,2,5,2,10,2,1107,19,10,3,8,102,-1,8,10,1001,10,1,10,4,10,1008,8,0,10,4,10,101,0,8,110,2,1007,10,10,2,1103,13,10,1006,0,34,3,8,102,-1,8,10,1001,10,1,10,4,10,108,1,8,10,4,10,102,1,8,142,1006,0,32,1,101,0,10,2,9,5,10,1006,0,50,3,8,1002,8,-1,10,1001,10,1,10,4,10,1008,8,1,10,4,10,101,0,8,179,1,1005,11,10,2,1108,11,10,1006,0,10,1,1004,3,10,3,8,1002,8,-1,10,101,1,10,10,4,10,1008,8,1,10,4,10,1002,8,1,216,1,1002,12,10,2,1102,3,10,1,1007,4,10,2,101,7,10,3,8,1002,8,-1,10,1001,10,1,10,4,10,108,0,8,10,4,10,102,1,8,253,2,104,3,10,1006,0,70,3,8,102,-1,8,10,1001,10,1,10,4,10,108,1,8,10,4,10,102,1,8,282,3,8,1002,8,-1,10,101,1,10,10,4,10,1008,8,0,10,4,10,101,0,8,305,101,1,9,9,1007,9,962,10,1005,10,15,99,109,647,104,0,104,1,21102,838211572492,1,1,21102,342,1,0,1105,1,446,21102,825326674840,1,1,21101,0,353,0,1106,0,446,3,10,104,0,104,1,3,10,104,0,104,0,3,10,104,0,104,1,3,10,104,0,104,1,3,10,104,0,104,0,3,10,104,0,104,1,21101,0,29086686211,1,21102,1,400,0,1106,0,446,21102,209420786919,1,1,21101,0,411,0,1105,1,446,3,10,104,0,104,0,3,10,104,0,104,0,21101,0,838337298792,1,21101,434,0,0,1105,1,446,21101,988661154660,0,1,21102,1,445,0,1106,0,446,99,109,2,21201,-1,0,1,21101,40,0,2,21101,0,477,3,21101,0,467,0,1105,1,510,109,-2,2106,0,0,0,1,0,0,1,109,2,3,10,204,-1,1001,472,473,488,4,0,1001,472,1,472,108,4,472,10,1006,10,504,1101,0,0,472,109,-2,2106,0,0,0,109,4,1201,-1,0,509,1207,-3,0,10,1006,10,527,21102,0,1,-3,22102,1,-3,1,22102,1,-2,2,21101,0,1,3,21101,546,0,0,1105,1,551,109,-4,2105,1,0,109,5,1207,-3,1,10,1006,10,574,2207,-4,-2,10,1006,10,574,21201,-4,0,-4,1105,1,642,21201,-4,0,1,21201,-3,-1,2,21202,-2,2,3,21102,1,593,0,1105,1,551,21202,1,1,-4,21102,1,1,-1,2207,-4,-2,10,1006,10,612,21102,0,1,-1,22202,-2,-1,-2,2107,0,-3,10,1006,10,634,21202,-1,1,1,21102,1,634,0,105,1,509,21202,-2,-1,-2,22201,-4,-2,-4,109,-5,2106,0,0

21
day11_test.go Normal file
View file

@ -0,0 +1,21 @@
package aoc2019
import "testing"
func TestCalculateDay11_Part1(t *testing.T) {
count, err := solveDay11Part1("day11_input.txt")
if err != nil {
t.Fatalf("Day 11 solver failed: %s", err)
}
t.Logf("Solution Day 11 Part 1: %d", count)
}
func TestCalculateDay11_Part2(t *testing.T) {
err := solveDay11Part2("day11_input.txt")
if err != nil {
t.Fatalf("Day 11 solver failed: %s", err)
}
t.Log("Solution Day 11 Part 2: See day11_image.png")
}