Skip to content

Instantly share code, notes, and snippets.

@msx80
Created December 20, 2018 13:23
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 msx80/8cb7315d097194472b1a22f764d5296d to your computer and use it in GitHub Desktop.
Save msx80/8cb7315d097194472b1a22f764d5296d to your computer and use it in GitHub Desktop.
package aoc;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Aoc16 {
interface Op{
int exec(int[] s, int a, int b);
}
enum OpCode {
ADDR( (s, a, b) -> s[a] + s[b]),
ADDI( (s, a, b) -> s[a] + b),
MULR( (s, a, b) -> s[a] * s[b]),
MULI( (s, a, b) -> s[a] * b),
BANR( (s, a, b) -> s[a] & s[b]),
BANI( (s, a, b) -> s[a] & b),
BORR( (s, a, b) -> s[a] | s[b]),
BORI( (s, a, b) -> s[a] | b),
SETR( (s, a, b) -> s[a]),
SETI( (s, a, b) -> a),
GTIR( (s, a, b) -> a > s[b] ? 1 : 0),
GTRI( (s, a, b) -> s[a] > b ? 1 : 0),
GTRR( (s, a, b) -> s[a] > s[b] ? 1 : 0),
EQIR( (s, a, b) -> a == s[b] ? 1 : 0),
EQRI( (s, a, b) -> s[a] == b ? 1 : 0),
EQRR( (s, a, b) -> s[a] == s[b] ? 1 : 0);
Op operation;
OpCode(Op operation)
{
this.operation = operation;
}
public boolean match(TestCase testCase) {
int[] state = testCase.before.clone();
exec( state, testCase.input[1], testCase.input[2], testCase.input[3]);
return Arrays.equals(state, testCase.after);
}
public void exec( int[] state, int a, int b, int c) {
int res = operation.exec(state, a, b);
state[c] = res;
}
}
static class TestCase{
int[] before;
int[] input;
int[] after;
public TestCase(String b, String i, String a)
{
b = b.substring(b.indexOf("[")+1, b.lastIndexOf("]")).replace(',', ' ');
a = a.substring(a.indexOf("[")+1, a.lastIndexOf("]")).replace(',', ' ');
before = parse4(b);
input = parse4(i);
after = parse4(a);
}
}
public static void main(String[] args) throws IOException {
Instant start = Instant.now();
List<String> lines = Files
.readAllLines(Paths.get("c:\\aoc16a.txt"))
.stream()
.collect(Collectors.toList());
List<TestCase> tests = new ArrayList<>();
for (int i = 0; i < lines.size(); i+=4) {
tests.add(new TestCase(lines.get(i), lines.get(i+1), lines.get(i+2) ));
}
findMatch3OrMore(tests);
Map<Integer, OpCode> opcodes = findOpcodes(tests);
execTestProgram(opcodes);
System.out.println(Duration.between(start, Instant.now()));
}
public static void execTestProgram(Map<Integer, OpCode> opcodes) throws IOException {
List<int[]> program = Files
.readAllLines(Paths.get("c:\\aoc16b.txt"))
.stream()
.map(Aoc16::parse4)
.collect(Collectors.toList());
int[] state = new int[4];
for (int[] instruction : program) {
opcodes.get(instruction[0]).exec(state, instruction[1], instruction[2], instruction[3]);
}
System.out.println("Final state: "+Arrays.toString(state));
}
private static Map<Integer, OpCode> findOpcodes(List<TestCase> tests) {
Map<Integer, OpCode> res = new HashMap<>();
Set<OpCode> toFind = new HashSet<>(Arrays.asList(OpCode.values()));
while(!toFind.isEmpty())
{
for (TestCase t : tests) {
Set<OpCode> matched = toFind.stream().filter(a -> a.match(t)).collect(Collectors.toSet());
if(matched.size() == 1 && !res.containsKey(t.input[0]))
{
OpCode o = matched.iterator().next();
res.put(t.input[0], o);
toFind.remove(o);
break;
}
}
}
return res;
}
public static void findMatch3OrMore(List<TestCase> tests) {
long match3 = tests.stream()
.filter(t -> countByTest(t) >= 3)
.count();
System.out.println("TestCases matching 3 or more ops: "+match3);
}
private static int countByTest(TestCase testCase) {
return (int) Stream.of(OpCode.values()).filter(o -> o.match(testCase)).count();
}
public static int[] parse4(String i) {
return Stream.of(i.split(" +")).mapToInt(Integer::parseInt).toArray();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment