Advertisement
Guest User

Untitled

a guest
Dec 19th, 2018
1,262
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 4.54 KB | None | 0 0
  1. package Advent2018;
  2.  
  3. import util.AdventOfCode;
  4.  
  5. import java.util.ArrayList;
  6. import java.util.Arrays;
  7. import java.util.List;
  8. import java.util.function.IntBinaryOperator;
  9. import java.util.function.ToIntFunction;
  10. import java.util.stream.IntStream;
  11.  
  12. public class Day19 extends AdventOfCode {
  13.  
  14.     int pointer;
  15.     int boundRegister;
  16.     List<Operation> instr;
  17.  
  18.     int largestDregister;
  19.  
  20.     int[] reg = new int[6];
  21.  
  22.  
  23.     class Operation {
  24.         int aReg;
  25.         int aVal;
  26.         int bReg;
  27.         int bVal;
  28.         int c;
  29.         Command cmd;
  30.  
  31.         public Operation(int aReg, int aVal, int bReg, int bVal, int c, Command cmd) {
  32.             this.aReg = aReg;
  33.             this.aVal = aVal;
  34.             this.bReg = bReg;
  35.             this.bVal = bVal;
  36.             this.c = c;
  37.             this.cmd = cmd;
  38.         }
  39.     }
  40.  
  41.     enum Command {
  42.         ADDR((x, y) -> x + y, Command::rr),
  43.         ADDI((x, y) -> x + y, Command::ri),
  44.         BANR((x, y) -> x & y, Command::rr),
  45.         BANI((x, y) -> x & y, Command::ri),
  46.         BORR((x, y) -> x | y, Command::rr),
  47.         BORI((x, y) -> x | y, Command::ri),
  48.         MULR((x, y) -> x * y, Command::rr),
  49.         MULI((x, y) -> x * y, Command::ri),
  50.         SETR((x, y) -> x, Command::rr),
  51.         SETI((x, y) -> x, Command::ir),
  52.         EQRI(Command::eq, Command::ri),
  53.         EQIR(Command::eq, Command::ir),
  54.         EQRR(Command::eq, Command::rr),
  55.         GTIR(Command::gt, Command::ir),
  56.         GTRR(Command::gt, Command::rr),
  57.         GTRI(Command::gt, Command::ri);
  58.  
  59.         static {
  60.             ADDI.secondReg = true;
  61.             BANI.secondReg = true;
  62.             BORI.secondReg = true;
  63.             MULI.secondReg = true;
  64.             EQRI.secondReg = true;
  65.             GTRI.secondReg = true;
  66.             SETI.secondReg = true; // ignore 2nd reg anyway
  67.             SETI.firstReg = true;
  68.             EQIR.firstReg = true;
  69.             GTIR.firstReg = true;
  70.         }
  71.  
  72.         boolean firstReg;
  73.         boolean secondReg;
  74.         IntBinaryOperator function;
  75.         ToIntFunction<Operation> opcode;
  76.         Command(IntBinaryOperator function, ToIntFunction<Operation> opcode) {
  77.             this.function = function;
  78.             this.opcode = opcode;
  79.         }
  80.  
  81.  
  82.         static int gt(int x, int y) {
  83.             return x > y ? 1 : 0;
  84.         }
  85.  
  86.         static int eq(int x, int y) {
  87.             return x == y ? 1 : 0;
  88.         }
  89.  
  90.         static int rr(Operation op) {
  91.             return op.cmd.function.applyAsInt(op.aReg, op.bReg);
  92.         }
  93.  
  94.         static int ri(Operation op) {
  95.             return op.cmd.function.applyAsInt(op.aReg, op.bVal);
  96.         }
  97.  
  98.         static int ir(Operation op) {
  99.             return op.cmd.function.applyAsInt(op.aVal, op.bReg);
  100.         }
  101.  
  102.     }
  103.     public Day19(List<String> input) {
  104.         super(input);
  105.     }
  106.  
  107.     boolean runProgram() {
  108.         Operation op = instr.get(pointer);
  109.         reg[boundRegister] = pointer;
  110.         if (!op.cmd.firstReg) {
  111.             op.aReg = reg[op.aVal];
  112.         }
  113.         if (!op.cmd.secondReg ) {
  114.             op.bReg = reg[op.bVal];
  115.         }
  116.         reg[op.c] = op.cmd.opcode.applyAsInt(op);
  117.        
  118.         // found
  119.         if (pointer == 32) return true;
  120.        
  121.         pointer = reg[boundRegister];
  122.         pointer++;
  123.         return false;
  124.     }
  125.  
  126.     @Override
  127.     public Object part1() {
  128.         while (pointer < instr.size()) {
  129.             runProgram();
  130.         }
  131.         return reg[0];
  132.     }
  133.  
  134.     int sumOfFactors(int n) {
  135.         return IntStream.range(1, n + 1)
  136.                 .filter(x -> n % x == 0)
  137.                 .sum();
  138.     }
  139.  
  140.     @Override
  141.     public Object part2() {
  142.         reg = new int[6];
  143.         reg[0] = 1;
  144.         pointer = 0;
  145.         while (pointer < instr.size()) {
  146.             boolean found = runProgram();
  147.             if (found) break;
  148.         }
  149.         return sumOfFactors(reg[2] + reg[5]);
  150.     }
  151.  
  152.     @Override
  153.     public void parse() {
  154.         instr = new ArrayList<>();
  155.         for (int i = 0; i < input.size(); i++) {
  156.             String[] split = input.get(i).split(" ");
  157.             if (i == 0) {
  158.                 boundRegister = Integer.parseInt(split[1]);
  159.             } else {
  160.                 Command cmd = Command.valueOf(split[0].toUpperCase());
  161.                 int a = Integer.parseInt(split[1]);
  162.                 int b = Integer.parseInt(split[2]);
  163.                 int c = Integer.parseInt(split[3]);
  164.                 Operation op = new Operation(a, a, b, b, c, cmd);
  165.                 instr.add(op);
  166.             }
  167.         }
  168.     }
  169.  
  170. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement