1
0

Day 3-6 2019

This commit is contained in:
2020-12-31 00:01:58 +01:00
parent 4fef41464e
commit ae327a4928
14 changed files with 1472 additions and 15 deletions
@@ -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);
}
}