Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package Advent2018;
- import util.AdventOfCode;
- import util.FileIO;
- import java.util.*;
- import java.util.function.IntBinaryOperator;
- import java.util.function.ToIntFunction;
- public class Day16 extends AdventOfCode {
- public Day16(List<String> input) {
- super(input);
- title = "Chronal Classification";
- part1Description = "Samples with 3 or more valid opcodes: ";
- part2Description = "Value at register 0 after running test program: ";
- }
- class Sample {
- int[] before = new int[4];
- int[] after = new int[4];
- int[] codes = new int[4];
- }
- List<Sample> samples;
- List<int[]> program;
- 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 {
- EQRI(Command::eq, Command::ri),
- BANI((x, y) -> x & y, Command::ri),
- SETI((x, y) -> x, Command::ir),
- BORI((x, y) -> x | y, Command::ri),
- EQIR(Command::eq, Command::ir),
- BANR((x, y) -> x & y, Command::rr),
- BORR((x, y) -> x | y, Command::rr),
- MULI((x, y) -> x * y, Command::ri),
- SETR((x, y) -> x, Command::rr),
- ADDR((x, y) -> x + y, Command::rr),
- EQRR(Command::eq, Command::rr),
- ADDI((x, y) -> x + y, Command::ri),
- GTIR(Command::gt, Command::ir),
- GTRR(Command::gt, Command::rr),
- GTRI(Command::gt, Command::ri),
- MULR((x, y) -> x * y, Command::rr);
- 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);
- }
- }
- void run(int[] reg, int[] codes, Command cmd) {
- int a = codes[1];
- int b = codes[2];
- int c = codes[3];
- Operation op = new Operation(reg[a], a, reg[b], b, reg[c], cmd);
- reg[codes[3]] = cmd.opcode.applyAsInt(op);
- }
- @Override
- public Object part1() {
- int hasthree = 0;
- // use this to order enums for part 2
- Map<Integer, Set<Command>> cmdmap = new HashMap<>();
- for (Sample sample : samples) {
- int count = 0;
- for (Command cmd : Command.values()) {
- int[] copy = new int[sample.before.length];
- System.arraycopy(sample.before, 0, copy, 0, sample.before.length);
- run(copy, sample.codes, cmd);;
- if (Arrays.equals(copy, sample.after)) {
- cmdmap.putIfAbsent(sample.codes[0], new HashSet<>());
- cmdmap.get(sample.codes[0]).add(cmd);
- count++;
- }
- }
- if (count > 2) hasthree++;
- }
- return hasthree;
- }
- @Override
- public Object part2() {
- int[] register = { 0, 0, 0, 0 };
- for (int[] line : program) {
- run(register, line, Command.values()[line[0]]);
- }
- return register[0];
- }
- @Override
- public void parse() {
- samples = new ArrayList<>();
- program = new ArrayList<>();
- boolean part2 = false;
- Sample sample = new Sample();
- samples.add(sample);
- for (String line : input) {
- if (line.equals("stop")) {
- part2 = true;
- continue;
- }
- if (part2) {
- program.add(FileIO.StringArrayToInt(line.split(" ")));
- } else {
- if (line.isEmpty()) {
- sample = new Sample();
- samples.add(sample);
- continue;
- }
- if (line.startsWith("Before")) {
- String[] split = line.substring(9, line.indexOf(']')).split(", ");
- sample.before = FileIO.StringArrayToInt(split);
- } else {
- if (line.startsWith("After")) {
- String[] split = line.substring(9, line.indexOf(']')).split(", ");
- sample.after = FileIO.StringArrayToInt(split);
- } else {
- sample.codes = FileIO.StringArrayToInt(line.split(" "));
- }
- }
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement