Skip to content

Instantly share code, notes, and snippets.

@snarkbait
Last active December 19, 2017 00:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save snarkbait/6aa90cc14421b9a2c1efd98f00dea0e1 to your computer and use it in GitHub Desktop.
Save snarkbait/6aa90cc14421b9a2c1efd98f00dea0e1 to your computer and use it in GitHub Desktop.
Advent of Code 2017 - Day 18
package Advent2017;
import java.util.function.LongBinaryOperator;
public enum Command {
snd((x, y) -> x),
add((x, y) -> x + y),
mul((x, y) -> x * y),
set((x, y) -> y),
mod((x, y) -> x % y),
rcv((x, y) -> x),
jgz((x, y) -> x > 0 ? y : 1);
LongBinaryOperator func;
Command(LongBinaryOperator func) { this.func = func;}
long apply(long x, long y) {
return this.func.applyAsLong(x, y);
}
}
package Advent2017;
import util.AdventOfCode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Day18 extends AdventOfCode {
Map<Character, Long> registers;
List<Instruction> instructions;
public Day18(List<String> input) {
super(input);
}
@Override
public Object part1() {
Program part1 = new Program(instructions, registers, true);
long result = 0L;
while (result == 0L) {
result = part1.next();
}
return result;
}
@Override
public Object part2() {
//reset
parse();
Program one = new Program(instructions, registers, false);
// clone registers
Map<Character, Long> register2 = new HashMap<>();
register2.putAll(registers);
register2.put('p', 1L);
Program two = new Program(instructions, register2, false);
// pair
one.pair(two);
two.pair(one);
// run
long sends = 0L;
while (!one.locked || !two.locked) {
if (!one.locked) one.next();
if (!two.locked) sends = two.next();
}
return sends;
}
@Override
public void parse() {
instructions = new ArrayList<>();
registers = new HashMap<>();
for (String each : input) {
String[] instr = each.split(" ");
Command cmd = Command.valueOf(instr[0]);
char register = instr[1].charAt(0);
registers.putIfAbsent(register, 0L);
if (register == '1') registers.put('1', 1L); /// OMG TOPAZ YOU BASTARD
long y = 0;
char toRegister = 'x';
if (instr.length > 2) {
try {
y = (long) Integer.parseInt(instr[2]);
} catch (NumberFormatException e) {
toRegister = instr[2].charAt(0);
}
}
instructions.add(new Instruction(cmd, register, y, toRegister));
}
}
}
package Advent2017;
public class Instruction {
Command cmd;
char register;
long y;
char toRegister;
public Instruction(Command cmd, char register, long y, char toRegister) {
this.cmd = cmd;
this.register = register;
this.y = y;
this.toRegister = toRegister;
}
}
package Advent2017;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
public class Program {
private int position;
Program duetProgram;
private Map<Character, Long> registers;
private List<Instruction> instructions;
Queue<Long> queue = new LinkedList<>();
boolean locked;
boolean part1;
private long lastSound;
int sends;
public Program(List<Instruction> instructions, Map<Character, Long> registers, boolean part1) {
this.instructions = instructions;
this.registers = registers;
this.part1 = part1;
}
public void pair(Program p) {
this.duetProgram = p;
}
public void receive(long a) {
if (locked) locked = false;
queue.add(a);
}
public void send(long val) {
sends++;
duetProgram.receive(val);
}
public long next() {
Instruction curr = instructions.get(position);
if (curr.toRegister != 'x') {
curr.y = registers.get(curr.toRegister);
}
long result = curr.cmd.apply(registers.get(curr.register), curr.y);
switch (curr.cmd) {
case snd:
if (part1) {
lastSound = result;
} else {
send(result);
}
position++;
break;
case rcv:
if (part1) {
if (result != 0) {
return lastSound;
}
} else {
if (queue.isEmpty()) {
locked = true;
return sends;
}
registers.put(curr.register, queue.remove());
}
position++;
break;
case jgz:
position += result;
break;
default:
registers.put(curr.register, result);
position++;
}
return 0L;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment