Day 3-6 2019
This commit is contained in:
@@ -1,15 +1,13 @@
|
||||
package be.vandewalleh.aoc.intcode;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Arrays;
|
||||
import java.util.Deque;
|
||||
|
||||
public class IntCodeInterpreter {
|
||||
private final Deque<Long> outputs = new ArrayDeque<>();
|
||||
private final long[] memory;
|
||||
|
||||
public IntCodeInterpreter(long[] memory) {
|
||||
var copy = new long[memory.length];
|
||||
System.arraycopy(memory, 0, copy, 0, memory.length);
|
||||
this.memory = copy;
|
||||
}
|
||||
private long input;
|
||||
|
||||
public IntCodeInterpreter(int[] memory) {
|
||||
this.memory = Arrays.stream(memory).asLongStream().toArray();
|
||||
@@ -23,26 +21,95 @@ public class IntCodeInterpreter {
|
||||
memory[2] = verb;
|
||||
}
|
||||
|
||||
public void setInput(long input) {
|
||||
this.input = input;
|
||||
}
|
||||
|
||||
public long getOutput() {
|
||||
return memory[0];
|
||||
}
|
||||
|
||||
// private ?
|
||||
public Deque<Long> getOutputs() {
|
||||
return outputs;
|
||||
}
|
||||
|
||||
private long readArgument(Mode mode, long param) {
|
||||
switch (mode) {
|
||||
case Positional -> {
|
||||
return memory[(int) param];
|
||||
}
|
||||
case Immediate -> {
|
||||
return param;
|
||||
}
|
||||
default -> throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
private void writeArgument(long param, long value) {
|
||||
memory[(int) param] = value;
|
||||
}
|
||||
|
||||
private Mode[] modes(long instruction) {
|
||||
var str = String.format("%5d", instruction).replace(' ', '0');
|
||||
return new Mode[]{
|
||||
Mode.of(str.charAt(2)),
|
||||
Mode.of(str.charAt(1)),
|
||||
Mode.of(str.charAt(0))
|
||||
};
|
||||
}
|
||||
|
||||
public void run() {
|
||||
var pointer = 0;
|
||||
|
||||
loop:
|
||||
while (true) {
|
||||
var optionalOpCode = OpCode.from((int) memory[pointer]);
|
||||
var opCode = optionalOpCode.orElseThrow(() -> new IllegalArgumentException("Invalid OpCode"));
|
||||
var jumped = false;
|
||||
var instruction = memory[pointer];
|
||||
var opCode = OpCode.from(((int) instruction) % 100);
|
||||
var args = Arrays.copyOfRange(memory, pointer + 1, pointer + opCode.params + 1);
|
||||
var modes = modes(instruction);
|
||||
switch (opCode) {
|
||||
case Add -> memory[(int) args[2]] = memory[(int) args[0]] + memory[(int) args[1]];
|
||||
case Multiply -> memory[(int) args[2]] = memory[(int) args[0]] * memory[(int) args[1]];
|
||||
case Add -> {
|
||||
var value = readArgument(modes[0], args[0]) + readArgument(modes[1], args[1]);
|
||||
writeArgument(args[2], value);
|
||||
}
|
||||
case Multiply -> {
|
||||
var value = readArgument(modes[0], args[0]) * readArgument(modes[1], args[1]);
|
||||
writeArgument(args[2], value);
|
||||
}
|
||||
case In -> {
|
||||
writeArgument(args[0], input);
|
||||
}
|
||||
case Out -> {
|
||||
outputs.push(readArgument(modes[0], args[0]));
|
||||
}
|
||||
case JumpIfTrue -> {
|
||||
if (readArgument(modes[0], args[0]) != 0) {
|
||||
pointer = (int) readArgument(modes[1], args[1]);
|
||||
jumped = true;
|
||||
}
|
||||
}
|
||||
case JumpIfFalse -> {
|
||||
if (readArgument(modes[0], args[0]) == 0) {
|
||||
pointer = (int) readArgument(modes[1], args[1]);
|
||||
jumped = true;
|
||||
}
|
||||
}
|
||||
case LessThan -> {
|
||||
var value = readArgument(modes[0], args[0]) < readArgument(modes[1], args[1]) ? 1 : 0;
|
||||
writeArgument(args[2], value);
|
||||
}
|
||||
case Equals -> {
|
||||
var value = readArgument(modes[0], args[0]) == readArgument(modes[1], args[1]) ? 1 : 0;
|
||||
writeArgument(args[2], value);
|
||||
}
|
||||
case Halt -> {
|
||||
break loop;
|
||||
}
|
||||
|
||||
}
|
||||
pointer += opCode.params + 1;
|
||||
if (!jumped) pointer += opCode.params + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
package be.vandewalleh.aoc.intcode;
|
||||
|
||||
public enum Mode {
|
||||
Positional, Immediate;
|
||||
|
||||
public static Mode of(char representation) {
|
||||
if (representation == '0') return Mode.Positional;
|
||||
else if (representation == '1') return Mode.Immediate;
|
||||
else throw new IllegalArgumentException("Unsupported Mode " + representation);
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,14 @@ import java.util.Optional;
|
||||
public enum OpCode {
|
||||
Add(1, 3),
|
||||
Multiply(2, 3),
|
||||
Halt(99, 0);
|
||||
Halt(99, 0),
|
||||
In(3, 1),
|
||||
Out(4, 1),
|
||||
JumpIfTrue(5, 2),
|
||||
JumpIfFalse(6, 2),
|
||||
LessThan(7, 3),
|
||||
Equals(8, 3),
|
||||
;
|
||||
|
||||
public final int value;
|
||||
public final int params;
|
||||
@@ -15,10 +22,10 @@ public enum OpCode {
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
public static Optional<OpCode> from(int value) {
|
||||
public static OpCode from(int value) {
|
||||
for (OpCode opCode : OpCode.values()) {
|
||||
if (opCode.value == value) return Optional.of(opCode);
|
||||
if (opCode.value == value) return opCode;
|
||||
}
|
||||
return Optional.empty();
|
||||
throw new IllegalArgumentException("Unsupported OpCode " + value);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user