Created
December 24, 2021 17:39
-
-
Save skyecodes/ba59dba57354fbec063f5e288facba45 to your computer and use it in GitHub Desktop.
This file contains 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
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