Part 1 works, part 2 is giving me trouble. I need to find a better way to validate whether 100x100 can fit, and then something faster to figure out the minimum position. In other words, the entire problem.
181 lines
3.3 KiB
Go
181 lines
3.3 KiB
Go
package days
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
u "parnic.com/aoc2019/utilities"
|
|
)
|
|
|
|
type Day19 struct {
|
|
program u.IntcodeProgram
|
|
}
|
|
|
|
func (d *Day19) Parse() {
|
|
d.program = u.LoadIntcodeProgram("19p")
|
|
}
|
|
|
|
func (d Day19) Num() int {
|
|
return 19
|
|
}
|
|
|
|
func (d *Day19) Part1() string {
|
|
grid := make([][]bool, 50)
|
|
for y := 0; y < len(grid); y++ {
|
|
grid[y] = make([]bool, 50)
|
|
}
|
|
|
|
count := int64(0)
|
|
|
|
for y := 0; y < 50; y++ {
|
|
for x := 0; x < 50; x++ {
|
|
d.program.Reset()
|
|
d.program.RunIn(func(inputStep int) int64 {
|
|
if inputStep == 1 {
|
|
return int64(x)
|
|
}
|
|
|
|
return int64(y)
|
|
}, func(val int64, state u.IntcodeProgramState) {
|
|
res := val == 1
|
|
grid[y][x] = res
|
|
if res {
|
|
count++
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// fmt.Println("50x50 tractor view:")
|
|
// for y := 0; y < len(grid); y++ {
|
|
// for x := 0; x < len(grid[y]); x++ {
|
|
// if grid[y][x] {
|
|
// fmt.Print("█")
|
|
// } else {
|
|
// fmt.Print(" ")
|
|
// }
|
|
// }
|
|
// fmt.Println()
|
|
// }
|
|
|
|
return fmt.Sprintf("Points affected in 50x50 area: %s%d%s", u.TextBold, count, u.TextReset)
|
|
}
|
|
|
|
func (d *Day19) Part2() string {
|
|
grid := make([][]bool, 5000)
|
|
for y := 0; y < len(grid); y++ {
|
|
grid[y] = make([]bool, 5000)
|
|
}
|
|
|
|
// find first hit
|
|
firstY := 0
|
|
for y := 1; firstY == 0; y++ {
|
|
for x := 0; x < 10*y; x++ {
|
|
d.program.Reset()
|
|
d.program.RunIn(func(inputStep int) int64 {
|
|
if inputStep == 1 {
|
|
return int64(x)
|
|
}
|
|
return int64(y)
|
|
}, func(val int64, state u.IntcodeProgramState) {
|
|
if val == 1 {
|
|
if firstY == 0 {
|
|
firstY = y
|
|
d.program.Stop()
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
done := false
|
|
y := firstY
|
|
x := 0
|
|
firstFoundX := 0
|
|
firstFoundY := 0
|
|
lastX := 0
|
|
lastY := 0
|
|
for y = firstY; !done; y++ {
|
|
lastFoundX := -1
|
|
for x = firstFoundX; lastFoundX == -1 || lastFoundX == x-1; x++ {
|
|
d.program.Reset()
|
|
d.program.RunIn(func(inputStep int) int64 {
|
|
if inputStep == 1 {
|
|
return int64(x)
|
|
}
|
|
|
|
return int64(y)
|
|
}, func(val int64, state u.IntcodeProgramState) {
|
|
res := val == 1
|
|
grid[y][x] = res
|
|
if res {
|
|
if lastFoundX == -1 {
|
|
firstFoundX = x
|
|
}
|
|
lastFoundX = x
|
|
}
|
|
})
|
|
}
|
|
|
|
if lastFoundX-firstFoundX+1 >= 100 {
|
|
if firstFoundY == 0 {
|
|
firstFoundY = y
|
|
}
|
|
done = grid[y-100][firstFoundX+100]
|
|
if done {
|
|
for checkY := y - 100; checkY <= y; checkY++ {
|
|
if !grid[checkY][firstFoundX+100] || !grid[checkY][firstFoundX] {
|
|
done = false
|
|
break
|
|
}
|
|
}
|
|
|
|
if done {
|
|
lastX = firstFoundX + 100
|
|
lastY = y
|
|
}
|
|
}
|
|
}
|
|
|
|
// if lastFoundX-firstFoundX+1 >= 100 {
|
|
// fmt.Printf("At y=%d, x reached %d for %d in a row\n", y, lastFoundX, lastFoundX-firstFoundX+1)
|
|
// }
|
|
}
|
|
|
|
for y := firstFoundY; y <= lastY; y++ {
|
|
for x = 0; ; x++ {
|
|
if grid[y][x] {
|
|
break
|
|
}
|
|
}
|
|
|
|
found := true
|
|
for y2 := y + 1; y2 < y+100; y2++ {
|
|
if !grid[y2][x] {
|
|
found = false
|
|
break
|
|
}
|
|
}
|
|
|
|
if found {
|
|
fmt.Printf("100 down, 100 across starts at y=%d, x=%d\n", y, x)
|
|
}
|
|
}
|
|
|
|
// fmt.Println("part 2 tractor view:")
|
|
// for y := 0; y < len(grid); y++ {
|
|
// for x := 0; x < len(grid[y]); x++ {
|
|
// if grid[y][x] {
|
|
// fmt.Print("█")
|
|
// } else {
|
|
// fmt.Print(" ")
|
|
// }
|
|
// }
|
|
// fmt.Println()
|
|
// }
|
|
|
|
origX := lastX - 100
|
|
origY := lastY - 100
|
|
result := (origX * 10000) + origY
|
|
return fmt.Sprintf("x=%d, y=%d, orig x=%d, orig y=%d, %s%d%s", lastX, lastY, origX, origY, u.TextBold, result, u.TextReset)
|
|
}
|