Jon Bristow

Posted on

# Advent of Code 2019 Solution Megathread - Day 19: Tractor Beam

Well, if Mark shows up, we have a way to keep him from tearing us apart now! It's an IntCode program!

### Day 19 - The Problem

After escaping from Triton, we took the tractor beam with us because it probably is going to help us tow Santa back in.

First, lets test the pull on this baby. Part 1 is to find the number of squares affected by the tractor beam. We can do this by sending drones out with our IntCode interpreter.

Now that we have the shape of the beam, lets try to find the closest we need to be to grab a sleigh sized object. Sleighs are probably 100x100, so in Part 2 we need to find the coordinates of the first 100*100 box covered by our beam.

### Ongoing Meta

If you were part of Ryan Palo's leaderboard last year, you're still a member of that!

I'll edit in any leaderboards that people want to post, along with any description for the kinds of people you want to have on it. (My leaderboard is being used as my office's leaderboard.) And if I get something wrong, please call me out or message me and I’ll fix it ASAP.

There's no limit to the number of leaderboards you can join, so there's no problem belonging to a "Beginner" and a language specific one if you want.

Jon Bristow

Kotlin solution! I had a lot of issues figuring out that I was off by one!

``````import arrow.core.Either
import arrow.core.None
import arrow.core.Some
import arrow.core.identity
import arrow.core.right
import arrow.optics.optics
import arrow.syntax.function.compose
import arrow.syntax.function.partially2
import intcode.CurrentState
import intcode.IntCode
import intcode.handleCodePoint
import intcode.toIntCodeProgram
import java.util.*

@optics
data class DroneController(
val code: IntCode,
val state: Either<String, CurrentState> = CurrentState().right()
) {
companion object
}

private tailrec fun DroneController.runCode(): DroneController {
return when (state) {
is Either.Left<String> -> this
is Either.Right<CurrentState> -> when (state.b.pointer) {
is None -> this
is Some<Long> -> {
copy(state = handleCodePoint(code, state)).runCode()
}
}
}
}

object Day19 {
private const val FILENAME = "src/main/resources/day19.txt"
val fileData get() = FILENAME.toIntCodeProgram()

val cache: MutableMap<PointL, Long> = mutableMapOf()

fun findPowerAt(p: PointL): Long {
return cache.getOrPut(p, {
DroneController(
code = fileData.toMutableMap(),
state = CurrentState(
).right()
).runCode().state.fold(
{ error("Unknonwn Problem at \$p") },
{ state -> state.output.pop() })
})
}

fun fourCorners(point: PointL, squareSize: Long) = listOf(
::identity,
PointL.x::modify::partially2{ it + squareSize },
PointL.x::modify::partially2{ it + squareSize } compose PointL.y::modify::partially2{ it - squareSize },
PointL.y::modify::partially2{ it - squareSize }
).all { findPowerAt(it(point)) == 1L }

fun part1() {
cache.clear()
println((0 until 50).flatMap { y ->
(0 until 50).map { x ->
PointL(x.toLong(), y.toLong())
}
}.map(::findPowerAt).count { it == 1L })
}

fun part2() {
val squareSize = 99L
cache.clear()
val n = generateSequence(squareSize) { it + 1 }.map { y ->
generateSequence(y * 0.7) { it + 1 }.takeWhile { it <= y }.map { x ->
PointL(x.toLong(), y.toLong())
}.dropWhile { findPowerAt(it) == 0L }.first()

}.dropWhile { !fourCorners(it, squareSize) }.first()
println(n.x * 10000 + n.y - squareSize)
}
}

fun main() {
Day19.part1()
Day19.part2()
}

``````