Skip to content

Instantly share code, notes, and snippets.

@rasmusfaber
Created December 17, 2019 10:14
Show Gist options
  • Save rasmusfaber/a8511165b7c44555cb18c89702b49fa6 to your computer and use it in GitHub Desktop.
Save rasmusfaber/a8511165b7c44555cb18c89702b49fa6 to your computer and use it in GitHub Desktop.
package dk.faberespensen.scratch.adventofcode.year2019.day17
import adventofcode.year2019.intcode.Machine
import dk.faberespensen.scratch.*
import dk.faberespensen.scratch.adventofcode.getInputLongsFromCsv
class Day17 {
val input = getInputLongsFromCsv(2019, 17)
fun part1() {
val map = getMap()
val res = map.positions().filter { map[it] == '#' && it.adjacentNonDiagonal().all { map[it] == '#' } }
.sumBy { it.x * it.y }
println(res)
}
private fun getMap(): XYMap<Char> {
val machine = Machine(input)
val sb = StringBuilder()
machine.sendOutput = { sb.append(it.toChar()) }
machine.run()
val output = sb.toString()
return output.toXYMap()
}
fun findSubFunctions(input: List<List<String>>, maxFunctionLength: Int, maxSubFunctions: Int): List<List<String>>? {
if (input.isEmpty()) {
return emptyList()
}
if (maxSubFunctions == 0) {
return null
}
for (i in 1..input[0].size) {
val candidate = input[0].subList(0, i)
if (candidate.joinToString(",").length > maxFunctionLength) {
break;
}
val fragments = input.flatMap { it.split(candidate) }.filter { it.isNotEmpty() }
val res = findSubFunctions(fragments, maxFunctionLength, maxSubFunctions - 1)
if (res != null) {
return res.plusAt(0, candidate)
}
}
return null;
}
fun part2() {
val map = getMap()
var path = makeSimplePath(map)
val res = findSubFunctions(listOf(path), 20, 3)
val (a, b, c) = res!!
path = path.replace(a, listOf("A"))
path = path.replace(b, listOf("B"))
path = path.replace(c, listOf("C"))
val machine = Machine(input)
machine.mem[0] = 2
machine.sendAsciiString(path.joinToString(",") + "\n")
machine.sendAsciiString(a.joinToString(",") + "\n")
machine.sendAsciiString(b.joinToString(",") + "\n")
machine.sendAsciiString(c.joinToString(",") + "\n")
machine.sendAsciiString("n\n")
machine.run()
println(machine.lastOutput)
}
fun makeSimplePath(map: XYMap<Char>): List<String> {
val start = map.positions().filter { map[it] == '^' }.single()
var direction = Direction.N
var pos = start
val visited = mutableSetOf<Pos>()
val res = mutableListOf<String>()
var forwardCount = 0
while (true) {
if (map[pos + direction] == '#') {
forwardCount++
pos += direction
} else if (map[pos + direction.turnRight()] == '#') {
if (forwardCount > 0) {
res.add(forwardCount.toString())
}
res.add("R")
direction = direction.turnRight()
forwardCount = 0
} else if (map[pos + direction.turnLeft()] == '#') {
if (forwardCount > 0) {
res.add(forwardCount.toString())
}
res.add("L")
direction = direction.turnLeft()
forwardCount = 0
} else {
res.add(forwardCount.toString())
return res
}
}
}
}
fun main(args: Array<String>) {
val d = Day17()
d.part1()
d.part2()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment