Skip to content

Instantly share code, notes, and snippets.

@skyecodes
Created December 24, 2021 17:39
Show Gist options
  • Save skyecodes/ba59dba57354fbec063f5e288facba45 to your computer and use it in GitHub Desktop.
Save skyecodes/ba59dba57354fbec063f5e288facba45 to your computer and use it in GitHub Desktop.
import java.io.IOException;
import java.util.List;
import java.util.function.IntBinaryOperator;
public class Day24 {
public static void main(String[] args) throws IOException {
var input = Util.readInput("Day24").stream().map(Instruction::parse).toList();
System.out.println("Part 1: " + part1(input));
}
static long part1(List<Instruction> input) {
long l = (long) (Math.pow(10, 14) - 1);
boolean b;
do {
b = new ALU(Long.toString(l--)).run(input);
if (l % 10 == 0) {
l--;
}
} while (!b);
return l;
}
static class ALU {
String modelNumber;
int modelNumberIndex;
int w, x, y, z;
ALU(String modelNumber) {
this.modelNumber = modelNumber;
}
boolean run(List<Instruction> instructions) {
instructions.forEach(i -> i.execute(this));
return z == 0;
}
int readInput() {
return Character.getNumericValue(modelNumber.charAt(modelNumberIndex++));
}
}
interface Instruction {
void execute(ALU alu);
static Instruction parse(String s) {
var split = s.split(" ");
var a = Operand.parse(split[1]);
if (split[0].equals("inp")) {
return alu -> a.set(alu, alu.readInput());
}
var b = Operand.parse(split[2]);
IntBinaryOperator op = switch (split[0]) {
case "add" -> Integer::sum;
case "mul" -> (x, y) -> x * y;
case "div" -> (x, y) -> x / y;
case "mod" -> (x, y) -> x % y;
case "eql" -> (x, y) -> x == y ? 1 : 0;
default -> throw new RuntimeException();
};
return alu -> a.set(alu, op.applyAsInt(a.get(alu), b.get(alu)));
}
}
interface Operand {
int get(ALU alu);
void set(ALU alu, int value);
static Operand parse(String s) {
return switch (s.charAt(0)) {
case 'w' -> Operand.W;
case 'x' -> Operand.X;
case 'y' -> Operand.Y;
case 'z' -> Operand.Z;
default -> Operand.value(Integer.parseInt(s));
};
}
static Operand value(int i) {
return new Operand() {
@Override
public int get(ALU alu) {
return i;
}
@Override
public void set(ALU alu, int value) {
throw new RuntimeException();
}
};
}
Operand W = new Operand() {
@Override
public int get(ALU alu) {
return alu.w;
}
@Override
public void set(ALU alu, int value) {
alu.w = value;
}
};
Operand X = new Operand() {
@Override
public int get(ALU alu) {
return alu.x;
}
@Override
public void set(ALU alu, int value) {
alu.x = value;
}
};
Operand Y = new Operand() {
@Override
public int get(ALU alu) {
return alu.y;
}
@Override
public void set(ALU alu, int value) {
alu.y = value;
}
};
Operand Z = new Operand() {
@Override
public int get(ALU alu) {
return alu.z;
}
@Override
public void set(ALU alu, int value) {
alu.z = value;
}
};
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment