2019 Day 19 Begun
This commit is contained in:
185
2019/day19/main.go
Normal file
185
2019/day19/main.go
Normal file
@@ -0,0 +1,185 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
intcode "git.bullercodeworks.com/brian/adventofcode/2019/intcode-processor"
|
||||
helpers "git.bullercodeworks.com/brian/adventofcode/helpers"
|
||||
)
|
||||
|
||||
var beam map[string]int
|
||||
var maxY int
|
||||
|
||||
func main() {
|
||||
pt := helpers.GetArgNumber(1)
|
||||
prog := intcode.ReadIntCodeFile("input")
|
||||
beam = make(map[string]int)
|
||||
if pt == "1" {
|
||||
part1(prog)
|
||||
} else {
|
||||
part2(prog)
|
||||
}
|
||||
}
|
||||
|
||||
func part1(prog []int) {
|
||||
var count int
|
||||
var lastRowStart int
|
||||
for y := 0; y < 50; y++ {
|
||||
var foundFirst bool
|
||||
fmt.Print(strings.Repeat(" ", lastRowStart))
|
||||
for x := lastRowStart; x < 50; x++ {
|
||||
out := runCodeAt(prog, x, y)
|
||||
fmt.Print(out)
|
||||
beam[c(x, y)] = out
|
||||
if out == 1 {
|
||||
if !foundFirst {
|
||||
lastRowStart = x
|
||||
}
|
||||
foundFirst = true
|
||||
count++
|
||||
} else if foundFirst {
|
||||
break
|
||||
}
|
||||
}
|
||||
fmt.Println()
|
||||
maxY = y
|
||||
}
|
||||
fmt.Println("Total:", count)
|
||||
}
|
||||
|
||||
func part2(prog []int) {
|
||||
shipSize := 100
|
||||
// Guesses
|
||||
//x, y := 0, 1000
|
||||
var x, square int
|
||||
bot, _ := 1025, 1037
|
||||
for square != shipSize {
|
||||
bot++
|
||||
fmt.Print("Calculating ", bot, "... ")
|
||||
square, x = maxSquare(prog, bot, bot/2)
|
||||
fmt.Println(square)
|
||||
}
|
||||
fmt.Println(x, bot)
|
||||
}
|
||||
|
||||
func part2Almost(prog []int) {
|
||||
shipSize := 100
|
||||
// Guesses
|
||||
x, y := 0, 1000
|
||||
var square int
|
||||
bot, top := 1026, 1037
|
||||
square, x = maxSquare(prog, y, 0)
|
||||
lastCheckRow := y
|
||||
for {
|
||||
if square > shipSize {
|
||||
y = y - (y-bot)/2
|
||||
} else if square < shipSize {
|
||||
y = y + (top-y)/2
|
||||
}
|
||||
if lastCheckRow == y {
|
||||
break
|
||||
}
|
||||
lastCheckRow = y
|
||||
fmt.Print("Calculating at ", y, "... ")
|
||||
square, x = maxSquare(prog, y, (y / 2))
|
||||
if square > 100 && y < top {
|
||||
top = y
|
||||
} else if square < 100 && y > bot {
|
||||
bot = y
|
||||
}
|
||||
fmt.Println("Square:", square)
|
||||
}
|
||||
fmt.Println("Final Square:", square)
|
||||
fmt.Println(x, y)
|
||||
}
|
||||
|
||||
func part2Slow(prog []int) {
|
||||
shipSize := 100
|
||||
var x, y int
|
||||
retX, retY := -1, -1
|
||||
var lastRowStart int
|
||||
for y = maxY; true; y++ {
|
||||
var foundFirst bool
|
||||
fmt.Print(strings.Repeat(" ", lastRowStart))
|
||||
for x = lastRowStart; x < y; x++ {
|
||||
out := runCodeAt(prog, x, y)
|
||||
fmt.Print(out)
|
||||
beam[c(x, y)] = out
|
||||
if out == 1 {
|
||||
if !foundFirst {
|
||||
lastRowStart = x
|
||||
}
|
||||
foundFirst = true
|
||||
} else if foundFirst {
|
||||
break
|
||||
}
|
||||
}
|
||||
square, _ := maxSquare(prog, y, lastRowStart)
|
||||
fmt.Println(":", square)
|
||||
// Every row, check what the maximum square is
|
||||
if square >= shipSize {
|
||||
retY, retX = y, lastRowStart
|
||||
break
|
||||
}
|
||||
}
|
||||
fmt.Println(retX, ",", retY)
|
||||
}
|
||||
|
||||
// maxSquare returns the square size and the bottom-left x position it starts at
|
||||
func maxSquare(prog []int, row, firstX int) (int, int) {
|
||||
for ; firstX < row; firstX++ {
|
||||
// Find the first X
|
||||
if runCodeAt(prog, firstX, row) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
var square int
|
||||
for d := 0; true; d++ {
|
||||
if runCodeAt(prog, firstX+d, row-d) == 0 {
|
||||
return square, firstX
|
||||
}
|
||||
square++
|
||||
}
|
||||
}
|
||||
return 0, firstX
|
||||
}
|
||||
|
||||
func runCodeAt(prog []int, x, y int) int {
|
||||
// If we've already cached this pos, just return it
|
||||
if v, ok := beam[c(x, y)]; ok {
|
||||
return v
|
||||
}
|
||||
|
||||
var res int
|
||||
p := intcode.NewProgram(prog)
|
||||
go func() {
|
||||
sendInputs(p, []int{x, y})
|
||||
res = getOutput(p)
|
||||
}()
|
||||
p.Run()
|
||||
|
||||
beam[c(x, y)] = res
|
||||
return res
|
||||
}
|
||||
|
||||
func sendInputs(p *intcode.Program, inp []int) {
|
||||
for k := range inp {
|
||||
for !p.NeedsInput() {
|
||||
time.Sleep(1)
|
||||
}
|
||||
p.Input(inp[k])
|
||||
}
|
||||
}
|
||||
|
||||
func getOutput(p *intcode.Program) int {
|
||||
for !p.NeedsOutput() {
|
||||
time.Sleep(1)
|
||||
}
|
||||
return p.Output()
|
||||
}
|
||||
|
||||
func c(x, y int) string {
|
||||
return fmt.Sprintf("[%d, %d]", x, y)
|
||||
}
|
||||
Reference in New Issue
Block a user