Last active
December 19, 2017 00:43
-
-
Save snarkbait/6aa90cc14421b9a2c1efd98f00dea0e1 to your computer and use it in GitHub Desktop.
Advent of Code 2017 - Day 18
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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