Skip to content

Commit

Permalink
feat: solve day 17 part 1
Browse files Browse the repository at this point in the history
  • Loading branch information
Flashky committed Dec 17, 2024
1 parent 4295802 commit 19a623e
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 58 deletions.
100 changes: 48 additions & 52 deletions src/main/java/com/adventofcode/flashk/day17/ChronospatialComputer.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,28 +13,30 @@ public class ChronospatialComputer {

private static final Pattern NUMBER_PATTERN = Pattern.compile("(\\d*)*");

private int A;
private int B;
private int C;
private int a;
private int b;
private int c;

private int[] program;
private int instructionPointer;
private StringJoiner outJoiner;
private boolean allowReservedOperand;

public ChronospatialComputer(List<String> inputs) {
A = Integer.parseInt(inputs.get(0).substring(12));
B = Integer.parseInt(inputs.get(1).substring(12));
C = Integer.parseInt(inputs.get(2).substring(12));
a = Integer.parseInt(inputs.get(0).substring(12));
b = Integer.parseInt(inputs.get(1).substring(12));
c = Integer.parseInt(inputs.get(2).substring(12));

String programValues = inputs.get(4).replace("Program: ", "");
program = Arrays.stream(programValues.split(",")).mapToInt(Integer::valueOf).toArray();

}

public String solveA() {
public String solveA(boolean allowReservedOperand) {

instructionPointer = 0;
outJoiner = new StringJoiner(",");
this.allowReservedOperand = allowReservedOperand;

int opcode;
int operator;
Expand All @@ -56,88 +58,82 @@ public String solveA() {
}

private void execute(int opcode, int operator) {
int operand = getOperand(operator);

switch(opcode) {
case 0: adv(operand); break;
case 1: bxl(operand); break;
case 2: bst(operand); break;
case 3: jnz(operand); break;
case 4: bxc(operand); break;
case 5: out(operand); break;
case 6: bdv(operand); break;
case 7: cdv(operand); break;
case 0: adv(operator); break;
case 1: bxl(operator); break;
case 2: bst(operator); break;
case 3: jnz(operator); break;
case 4: bxc(operator); break;
case 5: out(operator); break;
case 6: bdv(operator); break;
case 7: cdv(operator); break;
default: throw new IllegalArgumentException("Invalid opcode: "+opcode);
}
}

private int getOperand(int operator) {
private int getComboOperand(int operator) {
switch(operator) {
case 0,1,2,3:
return operator;
case 4:
return A;
return a;
case 5:
return B;
return b;
case 6:
return C;
return c;
default:
throw new IllegalArgumentException("Operand 7 is not a valid value");
if (allowReservedOperand) {
return operator;
}
throw new IllegalArgumentException("Invalid operator: "+operator);
}
}

private void adv(int operator) {
int power = (int) Math.pow(2, operator);
A = A / power;
private void adv(int operand) {
int comboOperand = getComboOperand(operand);
int power = (int) Math.pow(2, comboOperand);
a = a / power;

// TODO es posible que haya que truncar.
}

private void bxl(int operator) {
// TODO B = B XOR combo operator
// https://en.wikipedia.org/wiki/Bitwise_operation#XOR

// Steps:
// Convertir B de octal a binario.
// Convertir operator de octal a binario
// Hacer (B binario) XOR (operator binario) para cada bit.
// Reconvertir de binario a octal.

B = xor(B, operator);

private void bxl(int operand) {
b = xor(b, operand);
}

private void bst(int operator) {
B = operator % 8;
private void bst(int operand) {
int comboOperand = getComboOperand(operand);
b = comboOperand % 8;
}

private void jnz(int operator) {
if(A != 0) {
if(a != 0) {
instructionPointer = operator;
} else {
instructionPointer += 2;
}
}

private void bxc(int operator) {
// TODO B = B XOR C
private void bxc(int operand) {
// https://en.wikipedia.org/wiki/Bitwise_operation#XOR

B = xor(B, C);
b = xor(b, c);
}

private void out(int operator) {
int mod = operator % 8;
private void out(int operand) {
int comboOperand = getComboOperand(operand);
int mod = comboOperand % 8;
outJoiner.add(String.valueOf(mod));
}

private void bdv(int operator) {
B = A / (int) Math.pow(2, operator);

// TODO es posible que haya que truncar.
private void bdv(int operand) {
int comboOperand = getComboOperand(operand);
b = a / (int) Math.pow(2, comboOperand);
}

private void cdv(int operand) {
C = A / (int) Math.pow(2, operand);

// TODO es posible que haya que truncar.
int comboOperand = getComboOperand(operand);
c = a / (int) Math.pow(2, comboOperand);
}

private int xor(int a, int b) {
Expand Down
85 changes: 80 additions & 5 deletions src/test/java/com/adventofcode/flashk/day17/Day17Test.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,90 @@ public class Day17Test extends PuzzleTest {
@Tag(TestTag.PART_1)
@Tag(TestTag.SAMPLE)
@DisplayName(TestDisplayName.PART_1_DEBUG_1)
public void testSolvePart1Debug1() {
void part1Debug1Test() {

// Read input file
List<String> inputs = Input.readStringLines(INPUT_FOLDER, TestFilename.INPUT_FILE_SINGLE_SAMPLE);

ChronospatialComputer chronospatialComputer = new ChronospatialComputer(inputs);
chronospatialComputer.solveA();
chronospatialComputer.solveA(false);

assertEquals(1, chronospatialComputer.getB());
}

@Test
@Order(1)
@Tag(TestTag.PART_1)
@Tag(TestTag.SAMPLE)
@DisplayName(TestDisplayName.PART_1_DEBUG_2)
void part1Debug2Test() {

// Read input file
List<String> inputs = Input.readStringLines(INPUT_FOLDER, TestFilename.INPUT_FILE_SINGLE_SAMPLE_2);

ChronospatialComputer chronospatialComputer = new ChronospatialComputer(inputs);

assertEquals("0,1,2", chronospatialComputer.solveA(false));
}

@Test
@Order(1)
@Tag(TestTag.PART_1)
@Tag(TestTag.SAMPLE)
@DisplayName(TestDisplayName.PART_1_DEBUG_3)
void part1Debug3Test() {

// Read input file
List<String> inputs = Input.readStringLines(INPUT_FOLDER, TestFilename.INPUT_FILE_SINGLE_SAMPLE_3);

ChronospatialComputer chronospatialComputer = new ChronospatialComputer(inputs);

// TODO único test que se queda pillado.

// Register A: 2024
// Register B: 0
// Register C: 0

// Program: 0,1,5,4,3,0

assertEquals("4,2,5,6,7,7,7,7,3,1,0", chronospatialComputer.solveA(false));
assertEquals(0, chronospatialComputer.getA());
}

@Test
@Order(1)
@Tag(TestTag.PART_1)
@Tag(TestTag.SAMPLE)
@DisplayName(TestDisplayName.PART_1_DEBUG_4)
void part1Debug4Test() {

// Read input file
List<String> inputs = Input.readStringLines(INPUT_FOLDER, TestFilename.INPUT_FILE_SINGLE_SAMPLE_4);

ChronospatialComputer chronospatialComputer = new ChronospatialComputer(inputs);
chronospatialComputer.solveA(true);

// Se permite el operador reservado porque en este caso, el input tiene un operator 7 que hay que debuggear.

assertEquals(26, chronospatialComputer.getB());
}

@Test
@Order(1)
@Tag(TestTag.PART_1)
@Tag(TestTag.SAMPLE)
@DisplayName(TestDisplayName.PART_1_DEBUG_5)
void part1Debug5Test() {

// Read input file
List<String> inputs = Input.readStringLines(INPUT_FOLDER, TestFilename.INPUT_FILE_SINGLE_SAMPLE_5);

ChronospatialComputer chronospatialComputer = new ChronospatialComputer(inputs);
chronospatialComputer.solveA(false);

assertEquals(44354, chronospatialComputer.getB());
}

@Test
@Order(1)
@Tag(TestTag.PART_1)
Expand All @@ -53,7 +126,7 @@ public void testSolvePart1Sample() {

ChronospatialComputer chronospatialComputer = new ChronospatialComputer(inputs);

assertEquals("4,6,3,5,6,3,5,2,1,0", chronospatialComputer.solveA());
assertEquals("4,6,3,5,6,3,5,2,1,0", chronospatialComputer.solveA(false));
}

@Test
Expand All @@ -66,8 +139,10 @@ public void testSolvePart1Input() {
// Read input file
List<String> inputs = Input.readStringLines(INPUT_FOLDER, TestFilename.INPUT_FILE);
ChronospatialComputer chronospatialComputer = new ChronospatialComputer(inputs);
System.out.println("Solution: "+chronospatialComputer.solveA());
assertEquals(0L,0L);
System.out.println("Solution: "+chronospatialComputer.solveA(false));

// 3,4,5,0,5,4,1,5,0 -> Not valid
assertEquals("6,7,5,2,1,3,5,1,7",chronospatialComputer.solveA(false));

}

Expand Down
2 changes: 1 addition & 1 deletion src/test/resources/inputs

0 comments on commit 19a623e

Please sign in to comment.