Skip to content

Commit

Permalink
refactor: clean day 17 code
Browse files Browse the repository at this point in the history
  • Loading branch information
Flashky committed Dec 27, 2024
1 parent ac7e203 commit c5494e2
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 102 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import lombok.Getter;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
Expand All @@ -26,8 +25,6 @@ public class ChronospatialComputer {
private StringJoiner outJoiner;
private final String expectedProgram;

private List<ProgramState> programStates = new ArrayList<>();

public ChronospatialComputer(List<String> inputs) {
a = Long.parseLong(inputs.get(0).substring(12));
b = Long.parseLong(inputs.get(1).substring(12));
Expand Down Expand Up @@ -64,27 +61,10 @@ public String solveA() {

public long solveB() {

// TODO
// https://www.reddit.com/r/adventofcode/comments/1hn01ke/2024_day_17_part_2_code_works_until_certain/

// Aparentemente no basta con quedarse con el primer octal que verifique la condición.
// Puede haber más de un octal válido.
// Posible algoritmo recursivo con backtracking.
// Podría hacer el algoritmo como una mezcla recursiva e iterativa:
// - Recursivamente vamos bajando por dígitos (0 al 15)
// - Iterativamente, en cada llamda recursiva:
// - Generamos en un bucle los 8 posibles valores octales, llamamos a solveA para ver si es solución parcial.
// - Si es solución parcial, hacemos llamada recursiva, si no, iteramos al siguiente valor.
// Casos base:
// - Happy Path: dígito 16, y para el dígito octal elegido,la cadena generada es exactamente igual que la esperada

// Parámetros recursivos:
// - octal string: currentOctalDigit + octalDigit


return findRegistryA2(0, StringUtils.EMPTY, StringUtils.EMPTY);


}

private long findRegistryA2(int digit, String currentOctalNumber, String output) {
Expand Down Expand Up @@ -116,49 +96,6 @@ private long findRegistryA2(int digit, String currentOctalNumber, String output)
return -1;
}

private long findRegistryA(int digit, String currentOctalNumber, String output) {

// CB
if(digit == program.length) {
long result = Long.parseLong(currentOctalNumber, 8);
return expectedProgram.equals(output) ? result : -1;
// TODO probablemente pueda devolver directamente el número octal en decimal
}

// Caso recursivo
Map<Long,String> octalDigits = getOctalDigitCandidates(currentOctalNumber);

for(Map.Entry<Long,String> octalDigit : octalDigits.entrySet()) {
long result = findRegistryA(digit+1, currentOctalNumber+octalDigit.getKey(), octalDigit.getValue());

if(result != -1) {
return result;
}
}

return -1;
}

private Map<Long,String> getOctalDigitCandidates(String currentOctalNumber) {

Map<Long,String> validOctalDigits = new HashMap<>();

for(long octalDigit = 0; octalDigit < 8; octalDigit++) {

this.a = Long.parseLong(currentOctalNumber + octalDigit, 8);
this.b = 0;
this.c = 0;

String result = solveA();

if(expectedProgram.endsWith(result)) {
validOctalDigits.put(octalDigit, result);
}
}

return validOctalDigits;
}

private void execute(int opcode, int operator) {

switch(opcode) {
Expand All @@ -175,18 +112,13 @@ private void execute(int opcode, int operator) {
}

private long getComboOperand(int operator) {
switch(operator) {
case 0,1,2,3:
return operator;
case 4:
return a;
case 5:
return b;
case 6:
return c;
default:
throw new IllegalArgumentException("Invalid operator: "+operator);
}
return switch (operator) {
case 0, 1, 2, 3 -> operator;
case 4 -> a;
case 5 -> b;
case 6 -> c;
default -> throw new IllegalArgumentException("Invalid operator: " + operator);
};
}

private void adv(int operand) {
Expand Down
9 changes: 0 additions & 9 deletions src/main/java/com/adventofcode/flashk/day17/ProgramState.java

This file was deleted.

20 changes: 2 additions & 18 deletions src/test/java/com/adventofcode/flashk/day17/Day17Test.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

@DisplayName(TestDisplayName.DAY_17)
@TestMethodOrder(OrderAnnotation.class)
public class Day17Test extends PuzzleTest {
class Day17Test extends PuzzleTest {

private static final String INPUT_FOLDER = TestFolder.DAY_17;

Expand Down Expand Up @@ -181,15 +181,7 @@ public void testSolvePart2Input() {

ChronospatialComputer chronospatialComputer = new ChronospatialComputer(inputs);

// Algunas consideraciones:
// La primera operación con los datos reales es 2,4
// Esto es, opcode 2, operator 4:
// - opcode 2 implica BST, esto es b = comboOperand % 8;
// - operator 4 implica que el valor de comboOperand va a ser el registro A
// Por lo tanto, valga lo que valga A, b adquirirá el valor de A % 8

System.out.println("Solution: "+chronospatialComputer.solveB());
assertEquals(0L,0L);
assertEquals(216549846240877L,chronospatialComputer.solveB());

}

Expand All @@ -198,21 +190,13 @@ public void testSolvePart2Input() {
@Tag(TestTag.PART_2)
@Tag(TestTag.INPUT)
@DisplayName(TestDisplayName.PART_2_INPUT)
@Disabled("[Disabled] Day 17 - testSolvePart2Input: Work in Progress")
public void part2InputWithProgramTest() {

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

Program program = new Program(inputs);

// Algunas consideraciones:
// La primera operación con los datos reales es 2,4
// Esto es, opcode 2, operator 4:
// - opcode 2 implica BST, esto es b = comboOperand % 8;
// - operator 4 implica que el valor de comboOperand va a ser el registro A
// Por lo tanto, valga lo que valga A, b adquirirá el valor de A % 8

// Help: https://www.reddit.com/r/adventofcode/comments/1hn01ke/2024_day_17_part_2_code_works_until_certain/
assertEquals(216549846240877L, program.solveB());

Expand Down

0 comments on commit c5494e2

Please sign in to comment.