Created
December 17, 2019 10:14
-
-
Save rasmusfaber/a8511165b7c44555cb18c89702b49fa6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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