loading...
Cover image for Advent of Code 2019 Solution Megathread - Day 17: Set and Forget

Advent of Code 2019 Solution Megathread - Day 17: Set and Forget

jbristow profile image Jon Bristow ・2 min read

Gotta get rid of the dust before space-mom comes to see our space module!

Day 17 - The Problem

Oh no! We need to save our robot helpers! There's a solar flare on the way, and we need to use our trusty IntCode interpreter to use the Aft Scaffolding Control and Information Interface to help find a sleepy robot to help us out.

Part 1 has us examining the scaffolding and calculating the value of a bunch of intersections.

Part 2 requires us to send some code into the IntCode interpreter to instruct a little robot to tell the rest of its friends to get inside.

Ongoing Meta

Dev.to List of Leaderboards

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

If you want me to add your leaderboard code to this page, reply to one of these posts and/or send me a DM containing your code and any theming or notes you’d like me to add. (You can find your private leaderboard code on your "Private Leaderboard" page.)

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.

Neat Statistics

I'm planning on adding some statistics, but other than "what languages did we see yesterday" does anyone have any ideas?

Languages Seen On Day 16

Under construction

Posted on by:

jbristow profile

Jon Bristow

@jbristow

503 - Internal Server Error - TooCoolForSchoolException

Discussion

pic
Editor guide
 

Forgot to post the solution here. I tried to solve the part 2 in code and I couldn't find any way of doing it. As usual got the hint from R website and went ahead on manual way.

Swift solution

func partOne() {
    let computer = Opcode.init(input)
    var result: String = ""
    var outputs: [Int] = []
    while !computer.done {
        outputs.append(computer.run())
    }
    outputs.map { result.append(Character(UnicodeScalar($0)!))}

    let grid = result.split(separator: "\n").map{ $0.map{$0}}
    var sum = 0
    for row in 1 ..< (grid.count - 1) {
        for column in 1 ..< (grid[row].count - 1) {
            if grid[row][column] == "#" {
                if grid[row][column - 1] == "#" &&
                    grid[row][column + 1] == "#" &&
                    grid[row - 1][column] == "#" &&
                    grid[row + 1][column] == "#" {
                    sum += row * column
                }
            }
        }
    }
    print(grid)
    print("Part 1 answer is :\(sum)")
}

func partTwo() {
    var scanLine = ""
    let rules = """
    A,B,B,A,B,C,A,C,B,C
    L,4,L,6,L,8,L,12
    L,8,R,12,L,12
    R,12,L,6,L,6,L,8
    y\n
    """.map { Int($0.asciiValue!) }
    var rulesIndex = -1

    var dustCollected = 0
    input[0] = 2
    let computer = Opcode.init(input)
    while !computer.done {
        rulesIndex += 1
        computer.inputIds.append(rules[rulesIndex])
        let value = computer.run()
        dustCollected = value
    }

    print("Part 2 answer is :\(dustCollected)")
}

partOne()
partTwo()

Opcode and input can be found here

 

Woo! I got in the mid-900s for part 1!

However, part 2 doesn't seem to be working. It never asks for input and I don't know why! I was accidentally saving state between runs. DOH!

Kotlin solution for part 1

import arrow.core.Either
import arrow.core.None
import arrow.core.Some
import arrow.core.left
import arrow.core.right
import arrow.optics.optics
import intcode.CurrentState
import intcode.IntCode
import intcode.handleCodePoint
import intcode.toIntCodeProgram
import java.util.*

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

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

private fun Ascii.sendInput(): Ascii {
    return state.fold(
        ifLeft = { this },
        ifRight = {
            when {
                it.waitingForInput && inputs.isEmpty() -> copy(state = "Error: Attempted to get input with no inputs left.".left())
                it.waitingForInput -> {
                    val nInstr = inputs.pop()
                    it.inputs.add(nInstr.toLong())
                    copy(state = it.right())
                }
                else -> {
                    this
                }
            }
        }
    )
}

private tailrec fun Ascii.processOutput(): Ascii {
    return when (state) {
        is Either.Left<String> -> this
        is Either.Right<CurrentState> -> when {
            state.b.output.isEmpty() -> this
            else -> {
                val o = state.b.output.pop()
                when {
                    o > 127 -> println("NONASCII:$o")
                    else -> print(o.toChar())
                }
                output.add(o)
                if (o.toChar() == '\n') {
                    output.clear()
                }

                processOutput()
            }
        }
    }
}


object Day17 {
    private const val FILENAME = "src/main/resources/day17.txt"
    val fileData = FILENAME.toIntCodeProgram()

    fun part1() {
        val ascii = Ascii(code = fileData).runCode()
        println(ascii.output.joinToString("") { it.toChar().toString() })
        val points = ascii.output.joinToString("") { l -> "${l.toChar()}" }
            .lines().mapIndexed { y, line ->
                line.withIndex().filter { (_, c) -> c == '#' }
                    .map { (x, c) ->
                        Point(x, y) to c
                    }
            }.flatten().toMap()
        val intersections =
            points.filterKeys { p -> allDirections().map { d -> p.inDirection(d) }.all(points::contains) }.keys

        println(intersections.sumBy { p -> p.x * p.y })


    }

    val prog = "A,B,A,C,B,C,B,C,A,B\n" +
            "L,6,L,4,R,8\n" +
            "R,8,L,6,L,4,L,10,R,8\n" +
            "L,4,R,4,L,4,R,8\n" +
            "y\n"

    fun part2() {
        println(prog.lines().map { it.length })
        println(prog.map { b -> b.toLong() })
        val newCode = FILENAME.toIntCodeProgram().apply { this[0] = 2 }
        val ascii = Ascii(
            code = newCode,
            inputs = LinkedList(prog.map { it.toLong() }),
            state = CurrentState().right()
        ).runCode()

        println(ascii)
    }
}

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