Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package Advent2018;
- import util.AdventOfCode;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.List;
- import java.util.function.IntBinaryOperator;
- import java.util.function.ToIntFunction;
- import java.util.stream.IntStream;
- public class Day19 extends AdventOfCode {
- int pointer;
- int boundRegister;
- List<Operation> instr;
- int largestDregister;
- int[] reg = new int[6];
- class Operation {
- int aReg;
- int aVal;
- int bReg;
- int bVal;
- int c;
- Command cmd;
- public Operation(int aReg, int aVal, int bReg, int bVal, int c, Command cmd) {
- this.aReg = aReg;
- this.aVal = aVal;
- this.bReg = bReg;
- this.bVal = bVal;
- this.c = c;
- this.cmd = cmd;
- }
- }
- enum Command {
- ADDR((x, y) -> x + y, Command::rr),
- ADDI((x, y) -> x + y, Command::ri),
- BANR((x, y) -> x & y, Command::rr),
- BANI((x, y) -> x & y, Command::ri),
- BORR((x, y) -> x | y, Command::rr),
- BORI((x, y) -> x | y, Command::ri),
- MULR((x, y) -> x * y, Command::rr),
- MULI((x, y) -> x * y, Command::ri),
- SETR((x, y) -> x, Command::rr),
- SETI((x, y) -> x, Command::ir),
- EQRI(Command::eq, Command::ri),
- EQIR(Command::eq, Command::ir),
- EQRR(Command::eq, Command::rr),
- GTIR(Command::gt, Command::ir),
- GTRR(Command::gt, Command::rr),
- GTRI(Command::gt, Command::ri);
- static {
- ADDI.secondReg = true;
- BANI.secondReg = true;
- BORI.secondReg = true;
- MULI.secondReg = true;
- EQRI.secondReg = true;
- GTRI.secondReg = true;
- SETI.secondReg = true; // ignore 2nd reg anyway
- SETI.firstReg = true;
- EQIR.firstReg = true;
- GTIR.firstReg = true;
- }
- boolean firstReg;
- boolean secondReg;
- IntBinaryOperator function;
- ToIntFunction<Operation> opcode;
- Command(IntBinaryOperator function, ToIntFunction<Operation> opcode) {
- this.function = function;
- this.opcode = opcode;
- }
- static int gt(int x, int y) {
- return x > y ? 1 : 0;
- }
- static int eq(int x, int y) {
- return x == y ? 1 : 0;
- }
- static int rr(Operation op) {
- return op.cmd.function.applyAsInt(op.aReg, op.bReg);
- }
- static int ri(Operation op) {
- return op.cmd.function.applyAsInt(op.aReg, op.bVal);
- }
- static int ir(Operation op) {
- return op.cmd.function.applyAsInt(op.aVal, op.bReg);
- }
- }
- public Day19(List<String> input) {
- super(input);
- }
- boolean runProgram() {
- Operation op = instr.get(pointer);
- reg[boundRegister] = pointer;
- if (!op.cmd.firstReg) {
- op.aReg = reg[op.aVal];
- }
- if (!op.cmd.secondReg ) {
- op.bReg = reg[op.bVal];
- }
- reg[op.c] = op.cmd.opcode.applyAsInt(op);
- // found
- if (pointer == 32) return true;
- pointer = reg[boundRegister];
- pointer++;
- return false;
- }
- @Override
- public Object part1() {
- while (pointer < instr.size()) {
- runProgram();
- }
- return reg[0];
- }
- int sumOfFactors(int n) {
- return IntStream.range(1, n + 1)
- .filter(x -> n % x == 0)
- .sum();
- }
- @Override
- public Object part2() {
- reg = new int[6];
- reg[0] = 1;
- pointer = 0;
- while (pointer < instr.size()) {
- boolean found = runProgram();
- if (found) break;
- }
- return sumOfFactors(reg[2] + reg[5]);
- }
- @Override
- public void parse() {
- instr = new ArrayList<>();
- for (int i = 0; i < input.size(); i++) {
- String[] split = input.get(i).split(" ");
- if (i == 0) {
- boundRegister = Integer.parseInt(split[1]);
- } else {
- Command cmd = Command.valueOf(split[0].toUpperCase());
- int a = Integer.parseInt(split[1]);
- int b = Integer.parseInt(split[2]);
- int c = Integer.parseInt(split[3]);
- Operation op = new Operation(a, a, b, b, c, cmd);
- instr.add(op);
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement