Skip to content

Commit 8ae57b5

Browse files
committed
day 5 was so cool
1 parent bc01173 commit 8ae57b5

File tree

4 files changed

+167
-35
lines changed

4 files changed

+167
-35
lines changed

2019/inputs/day05/input.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3,225,1,225,6,6,1100,1,238,225,104,0,1102,9,19,225,1,136,139,224,101,-17,224,224,4,224,102,8,223,223,101,6,224,224,1,223,224,223,2,218,213,224,1001,224,-4560,224,4,224,102,8,223,223,1001,224,4,224,1,223,224,223,1102,25,63,224,101,-1575,224,224,4,224,102,8,223,223,1001,224,4,224,1,223,224,223,1102,55,31,225,1101,38,15,225,1001,13,88,224,1001,224,-97,224,4,224,102,8,223,223,101,5,224,224,1,224,223,223,1002,87,88,224,101,-3344,224,224,4,224,102,8,223,223,1001,224,7,224,1,224,223,223,1102,39,10,225,1102,7,70,225,1101,19,47,224,101,-66,224,224,4,224,1002,223,8,223,1001,224,6,224,1,224,223,223,1102,49,72,225,102,77,166,224,101,-5544,224,224,4,224,102,8,223,223,1001,224,4,224,1,223,224,223,101,32,83,224,101,-87,224,224,4,224,102,8,223,223,1001,224,3,224,1,224,223,223,1101,80,5,225,1101,47,57,225,4,223,99,0,0,0,677,0,0,0,0,0,0,0,0,0,0,0,1105,0,99999,1105,227,247,1105,1,99999,1005,227,99999,1005,0,256,1105,1,99999,1106,227,99999,1106,0,265,1105,1,99999,1006,0,99999,1006,227,274,1105,1,99999,1105,1,280,1105,1,99999,1,225,225,225,1101,294,0,0,105,1,0,1105,1,99999,1106,0,300,1105,1,99999,1,225,225,225,1101,314,0,0,106,0,0,1105,1,99999,1008,677,226,224,1002,223,2,223,1005,224,329,1001,223,1,223,107,226,677,224,1002,223,2,223,1006,224,344,101,1,223,223,1007,677,677,224,1002,223,2,223,1006,224,359,1001,223,1,223,8,677,226,224,102,2,223,223,1005,224,374,101,1,223,223,108,226,677,224,102,2,223,223,1006,224,389,1001,223,1,223,1008,677,677,224,1002,223,2,223,1006,224,404,1001,223,1,223,1107,677,677,224,102,2,223,223,1005,224,419,1001,223,1,223,1008,226,226,224,102,2,223,223,1005,224,434,101,1,223,223,8,226,677,224,1002,223,2,223,1006,224,449,101,1,223,223,1007,677,226,224,102,2,223,223,1005,224,464,1001,223,1,223,107,677,677,224,1002,223,2,223,1005,224,479,1001,223,1,223,1107,226,677,224,1002,223,2,223,1005,224,494,1001,223,1,223,7,677,677,224,102,2,223,223,1006,224,509,101,1,223,223,1007,226,226,224,1002,223,2,223,1005,224,524,101,1,223,223,7,677,226,224,102,2,223,223,1005,224,539,101,1,223,223,8,226,226,224,1002,223,2,223,1006,224,554,101,1,223,223,7,226,677,224,102,2,223,223,1005,224,569,101,1,223,223,1108,677,226,224,1002,223,2,223,1005,224,584,101,1,223,223,108,677,677,224,1002,223,2,223,1006,224,599,101,1,223,223,107,226,226,224,1002,223,2,223,1006,224,614,101,1,223,223,1108,226,226,224,1002,223,2,223,1005,224,629,1001,223,1,223,1107,677,226,224,1002,223,2,223,1005,224,644,101,1,223,223,108,226,226,224,1002,223,2,223,1005,224,659,101,1,223,223,1108,226,677,224,1002,223,2,223,1005,224,674,1001,223,1,223,4,223,99,226
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,136 @@
11
package adventofcode.common
22

3+
import java.io.File
4+
5+
enum class ParameterMode {
6+
Position,
7+
Immediate;
8+
9+
companion object {
10+
public fun decode(modeVal: Int) = ParameterMode.values()[modeVal]
11+
}
12+
}
13+
14+
data class Instruction(public val opcode: Int, public val modes: List<ParameterMode>) {
15+
companion object {
16+
fun decode(encoded: Int): Instruction {
17+
// Get the opcode, which is the lower two digits
18+
val opcode = encoded % 100
19+
var modeFlags = encoded / 100
20+
21+
val modes = generateSequence {
22+
if (modeFlags == 0) {
23+
null
24+
} else {
25+
val mode = ParameterMode.decode(modeFlags % 10)
26+
modeFlags = modeFlags / 10
27+
mode
28+
}
29+
}.toList()
30+
31+
return Instruction(opcode, modes)
32+
}
33+
}
34+
35+
public fun modeFor(parameterIndex: Int) =
36+
if (parameterIndex >= modes.size) {
37+
ParameterMode.Position
38+
} else {
39+
modes[parameterIndex]
40+
}
41+
}
42+
343
public class IntcodeComputer(public var memory: IntArray, private val trace: Boolean = false) {
444
public var programCounter = 0
545

46+
companion object {
47+
public fun fromProgram(input: String, trace: Boolean = false): IntcodeComputer {
48+
val memory = input.split(",").map { it.toInt() }.toIntArray()
49+
return IntcodeComputer(memory, trace)
50+
}
51+
52+
public fun fromProgramFile(inputFile: String, trace: Boolean = false): IntcodeComputer =
53+
fromProgram(File(inputFile).readText().trim(), trace)
54+
}
55+
56+
private fun readNext(): Int {
57+
val value = memory[programCounter]
58+
programCounter += 1
59+
return value
60+
}
61+
62+
private fun readNextByMode(mode: ParameterMode): Int {
63+
val value = readNext()
64+
65+
return when (mode) {
66+
ParameterMode.Position -> memory[value]
67+
ParameterMode.Immediate -> value
68+
}
69+
}
70+
671
// Run a single step of the program
772
public fun step(): Boolean {
8-
val opcode = memory[programCounter]
73+
var startPc = programCounter
74+
val instruction = Instruction.decode(readNext())
975

10-
if (opcode == 99) {
11-
return false
12-
}
76+
fun execBinop(op: (Int, Int) -> Int) {
77+
val x = readNextByMode(instruction.modeFor(0))
78+
val y = readNextByMode(instruction.modeFor(1))
79+
memory[readNext()] = op(x, y)
80+
}
81+
82+
fun jumpIf(cond: (Int) -> Boolean) {
83+
val x = readNextByMode(instruction.modeFor(0))
84+
85+
// Must read the target even if we don't set it.
86+
val loc = readNextByMode(instruction.modeFor(1))
87+
if (cond(x)) {
88+
programCounter = loc
89+
}
90+
}
1391

14-
val input1Addr = memory[programCounter + 1]
15-
val input2Addr = memory[programCounter + 2]
16-
val outputAddr = memory[programCounter + 3]
92+
when (instruction.opcode) {
93+
// Add
94+
1 -> execBinop { x, y -> x + y }
1795

18-
// Load inputs
19-
val input1 = memory[input1Addr]
20-
val input2 = memory[input2Addr]
96+
// Mult
97+
2 -> execBinop { x, y -> x * y }
2198

22-
// Perform operation and store output
23-
memory[outputAddr] = execute(opcode, input1, input2)
99+
// Output
100+
3 -> {
101+
print("[Intcode] INPUT: ")
102+
val input = readLine()!!.trim().toInt()
103+
memory[readNext()] = input
104+
}
105+
106+
// Input
107+
4 -> {
108+
val x = readNextByMode(instruction.modeFor(0))
109+
println("[Intcode] OUTPUT: $x")
110+
}
111+
112+
// Jump if true
113+
5 -> jumpIf { it != 0 }
114+
115+
// Jump if false
116+
6 -> jumpIf { it == 0 }
117+
118+
// Test less than
119+
7 -> execBinop { x, y -> if (x < y) { 1 } else { 0 } }
120+
121+
// Test equals
122+
8 -> execBinop { x, y -> if (x == y) { 1 } else { 0 } }
123+
124+
99 -> {
125+
return false
126+
}
127+
else -> throw Exception("Unknown opcode: ${instruction.opcode}")
128+
}
24129

25130
if (trace) {
26-
dumpState()
131+
dumpState(instruction, startPc, programCounter)
27132
}
28133

29-
programCounter += 4
30134
return true
31135
}
32136

@@ -35,17 +139,16 @@ public class IntcodeComputer(public var memory: IntArray, private val trace: Boo
35139
while (step()) {}
36140
}
37141

38-
private fun execute(opcode: Int, input1: Int, input2: Int): Int =
39-
if (opcode == 1) {
40-
input1 + input2
41-
} else if (opcode == 2) {
42-
input1 * input2
43-
} else {
44-
throw Exception("Unexpected opcode: $opcode");
45-
}
46-
47-
private fun dumpState() {
48-
val dump = memory.map { it.toString() }.joinToString(",")
49-
println("State: $dump")
142+
private fun dumpState(instruction: Instruction, startPc: Int, endPc: Int) {
143+
val dump = memory.mapIndexed { idx, i ->
144+
if (idx == startPc) {
145+
"{$i}"
146+
} else if(idx == endPc) {
147+
"[$i]"
148+
} else {
149+
"$i"
150+
}
151+
}.joinToString(",")
152+
println("${instruction.opcode} => $dump")
50153
}
51-
}
154+
}
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
package adventofcode.day05
22

3+
import adventofcode.common.IntcodeComputer
4+
35
fun main(args: Array<String>) {
4-
val inputFile = if (args.size < 1) {
5-
System.err.println("Usage: adventofcode day05 <INPUT FILE>")
6-
System.exit(1)
7-
throw Exception("Whoop")
8-
} else {
9-
args[0]
10-
}
11-
println("Using input file $inputFile");
6+
println("Use the 'intcode' command instead!")
7+
System.exit(1)
128
}

2019/src/main/kotlin/adventofcode/main.kt

+32
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,20 @@ package adventofcode
22

33
import java.io.File;
44

5+
import adventofcode.common.IntcodeComputer
6+
57
fun main(args: Array<String>) {
68
if (args.size < 1 || args[0] == "help") {
79
println("Usage: adventofcode <dayNumber> <ARGS...>")
810
System.exit(1)
911
}
1012

13+
if (args[0] == "intcode") {
14+
println("Running Intcode computer")
15+
runIntcode(args.drop(1))
16+
return
17+
}
18+
1119
val dayName = if (args[0].startsWith("day")) {
1220
args[0].substring(3)
1321
} else {
@@ -26,4 +34,28 @@ fun main(args: Array<String>) {
2634
6 -> adventofcode.day06.main(args.drop(1).toTypedArray())
2735
else -> throw Exception("Day not yet implemented: $dayNumber")
2836
}
37+
}
38+
39+
fun runIntcode(a: List<String>) {
40+
var args = a
41+
42+
val trace = args.contains("--trace")
43+
if (trace) {
44+
args = args.filterNot { it == "--trace" }
45+
}
46+
47+
if (args.size < 1) {
48+
System.err.println("Usage: adventofcode intcode <PROGRAM>")
49+
System.err.println("Usage: adventofcode intcode @<PROGRAMFILE>")
50+
System.exit(1)
51+
}
52+
53+
val program = if (args[0].startsWith("@")) {
54+
File(args[0].substring(1)).readText().trim()
55+
} else {
56+
args[0]
57+
}
58+
59+
val computer = IntcodeComputer.fromProgram(program, trace)
60+
computer.runToHalt()
2961
}

0 commit comments

Comments
 (0)