val input = readText("y2019/w1/d05/input.txt") fun main() { val program = input.split(",").map(String::toInt).toMutableList() println("Part 1: " + run(program, listOf(1))) println("Part 2: " + run(program, listOf(5))) } private fun run(program: List, input: List): List { val memory = program.toMutableList() val inputLeft = ArrayDeque(input) val output = mutableListOf() var instrPtr = 0; loop@ while (true) { val instruction = memory[instrPtr].toString() val opCode = instruction.takeLast(2).toInt() val modes = instruction.dropLast(2).reversed().map { it.digit() } fun mode(offset: Int) = modes.getOrElse(offset - 1) { 0 } fun read(offset: Int) = when (val mode = mode(offset)) { 0 -> memory[memory[instrPtr + offset]] 1 -> memory[instrPtr + offset] else -> error("Unknown mode $mode") } fun write(offset: Int, value: Int) { check(mode(offset) == 0) { "Require mode 0 for writing, got ${mode(offset)}" } memory[memory[instrPtr + offset]] = value } when (opCode) { 1, 2 -> { //add, mul val op: (Int, Int) -> Int = if (opCode == 1) Int::plus else Int::times write(3, op(read(1), read(2))) instrPtr += 4 } 3 -> { //input write(1, inputLeft.pop()) instrPtr += 2 } 4 -> { //output output += read(1) instrPtr += 2 } 5, 6 -> { //jump-if-true, jump-if-false val expectTrue = opCode == 5 if ((read(1) == 0) xor expectTrue) instrPtr = read(2) else instrPtr += 3 } 7, 8 -> { //lt, eq val cmp = if (opCode == 7) -1 else 0 write(3, if (read(1).compareTo(read(2)) == cmp) 1 else 0) instrPtr += 4 } 99 -> break@loop else -> error("Unknown opCode $opCode") } } return output }