Skip to content

Commit

Permalink
feat: solve day 21 WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
Flashky committed Dec 22, 2024
1 parent 982e1f2 commit 5657b04
Show file tree
Hide file tree
Showing 8 changed files with 483 additions and 3 deletions.
79 changes: 79 additions & 0 deletions src/main/java/com/adventofcode/flashk/day21/DirectionalKeypad.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package com.adventofcode.flashk.day21;

import lombok.Setter;
import org.jgrapht.Graph;
import org.jgrapht.GraphPath;
import org.jgrapht.alg.shortestpath.DijkstraShortestPath;
import org.jgrapht.graph.DirectedMultigraph;


public class DirectionalKeypad {

public static final Character UP = '^';
public static final Character DOWN = 'v';
public static final Character LEFT = '<';
public static final Character RIGHT = '>';
public static final Character ACCEPT = 'A';
public static final String ACCEPT_TO_LEFT = "v<<";
public static final String LEFT_TO_ACCEPT = "^>>";
public static final String DOWN_TO_ACCEPT = ">^";

private Graph<Character,PadEdge> graph = new DirectedMultigraph<>(PadEdge.class);
private DijkstraShortestPath<Character,PadEdge> dijkstraShortestPath = new DijkstraShortestPath<>(graph);

@Setter
private Character currentKey = ACCEPT;

public DirectionalKeypad() {
graph.addVertex(LEFT);
graph.addVertex(DOWN);
graph.addVertex(UP);
graph.addVertex(RIGHT);
graph.addVertex(ACCEPT);

graph.addEdge(LEFT, DOWN, new PadEdge(RIGHT));
graph.addEdge(LEFT,ACCEPT, new PadEdge(LEFT_TO_ACCEPT));

graph.addEdge(DOWN, LEFT, new PadEdge(LEFT));
graph.addEdge(DOWN, UP, new PadEdge(UP));
graph.addEdge(DOWN, RIGHT, new PadEdge(RIGHT));
graph.addEdge(DOWN, ACCEPT, new PadEdge(DOWN_TO_ACCEPT));

graph.addEdge(UP, DOWN, new PadEdge(DOWN));
graph.addEdge(UP, ACCEPT, new PadEdge(RIGHT));

graph.addEdge(RIGHT, DOWN, new PadEdge(LEFT));
graph.addEdge(RIGHT, ACCEPT, new PadEdge(UP));

graph.addEdge(ACCEPT, UP, new PadEdge(LEFT));
graph.addEdge(ACCEPT, RIGHT, new PadEdge(DOWN));
graph.addEdge(ACCEPT, LEFT, new PadEdge(ACCEPT_TO_LEFT)); // new

}

/// Enters a code, such as `029A`, returning a [String] representing the needed moves for it.
/// @param code the code to enter.
/// @return The String that represents the performed movements to enter that code at the numpad.
public String press(String code) {
char[] buttons = code.toCharArray();

StringBuilder sb = new StringBuilder();
for(char button : buttons) {
sb.append(press(button));
}

return sb.toString();
}

private String press(char button) {

GraphPath<Character, PadEdge> path = dijkstraShortestPath.getPath(currentKey, button);
StringBuilder sb = new StringBuilder();
for(PadEdge edge : path.getEdgeList()) {
sb.append(edge.label());
}
sb.append(ACCEPT);
currentKey = button;
return sb.toString();
}
}
49 changes: 49 additions & 0 deletions src/main/java/com/adventofcode/flashk/day21/KeypadConundrum.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.adventofcode.flashk.day21;


import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.List;

public class KeypadConundrum {

private Numpad numpadRobot = new Numpad();
private List<DirectionalKeypad> directionalKeypads = new ArrayList<>();

private List<String> codes;

public KeypadConundrum(List<String> inputs) {
codes = inputs;
}

public long solveA() {

long result = 0;
directionalKeypads.add(new DirectionalKeypad());
directionalKeypads.add(new DirectionalKeypad());


for(String code : codes) {
result += press(code);
}

return result;
}

private long press(String code) {
String movements = numpadRobot.press(code);
String directionalMovements = StringUtils.EMPTY;

for(DirectionalKeypad directionalKeypad : directionalKeypads) {

directionalMovements = directionalKeypad.press(movements);
movements = directionalMovements;
}

long shortestSequenceLength = directionalMovements.length();
long numericValue = Long.parseLong(code.replace("A", StringUtils.EMPTY));

return shortestSequenceLength * numericValue;
}
}
182 changes: 182 additions & 0 deletions src/main/java/com/adventofcode/flashk/day21/Numpad.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
package com.adventofcode.flashk.day21;

import org.jgrapht.Graph;
import org.jgrapht.GraphPath;
import org.jgrapht.alg.shortestpath.DijkstraShortestPath;

import org.jgrapht.graph.DirectedMultigraph;
import org.jgrapht.graph.DirectedWeightedMultigraph;

import java.util.List;

public class Numpad {

public static final Character BUTTON_0 = '0';
public static final Character BUTTON_1 = '1';
public static final Character BUTTON_2 = '2';
public static final Character BUTTON_3 = '3';
public static final Character BUTTON_4 = '4';
public static final Character BUTTON_5 = '5';
public static final Character BUTTON_6 = '6';
public static final Character BUTTON_7 = '7';
public static final Character BUTTON_8 = '8';
public static final Character BUTTON_9 = '9';
public static final Character ACCEPT = 'A';
private static final String BUTTON_2_TO_BUTTON_9 = ">^^";
private static final String BUTTON_9_TO_BUTTON_2 = "vv<";

private Graph<Character,PadEdge> graph = new DirectedWeightedMultigraph<>(PadEdge.class);

private DijkstraShortestPath<Character,PadEdge> dijkstraShortestPath = new DijkstraShortestPath<>(graph);

private Character currentKey = ACCEPT;

public Numpad() {

graph.addVertex(BUTTON_0);
graph.addVertex(BUTTON_1);
graph.addVertex(BUTTON_2);
graph.addVertex(BUTTON_3);
graph.addVertex(BUTTON_4);
graph.addVertex(BUTTON_5);
graph.addVertex(BUTTON_6);
graph.addVertex(BUTTON_7);
graph.addVertex(BUTTON_8);
graph.addVertex(BUTTON_9);
graph.addVertex(ACCEPT);


// TODO problema con los ejes
// Labeled edges in multigraph MUST BE unique, so an String or Character is not enough:
// https://jgrapht.org/guide/VertexAndEdgeTypes#labeled-edges-in-a-multigraph

// modelar ejes con un record único.


// cada eje debería tener un nombre único
PadEdge padEdge;

graph.addEdge(BUTTON_0, BUTTON_2, new PadEdge(DirectionalKeypad.UP));
graph.setEdgeWeight(BUTTON_0, BUTTON_2, 2);

graph.addEdge(BUTTON_0, ACCEPT, new PadEdge(DirectionalKeypad.RIGHT));
graph.setEdgeWeight(BUTTON_0, ACCEPT, 1);

graph.addEdge(BUTTON_1, BUTTON_2, new PadEdge(DirectionalKeypad.RIGHT));
graph.setEdgeWeight(BUTTON_1, BUTTON_2, 2);

graph.addEdge(BUTTON_1, BUTTON_4, new PadEdge(DirectionalKeypad.UP));
graph.setEdgeWeight(BUTTON_1, BUTTON_4, 3);

graph.addEdge(BUTTON_2, BUTTON_0, new PadEdge(DirectionalKeypad.DOWN));
graph.setEdgeWeight(BUTTON_2, BUTTON_0, 2);

graph.addEdge(BUTTON_2, BUTTON_1, new PadEdge(DirectionalKeypad.LEFT));
graph.setEdgeWeight(BUTTON_2, BUTTON_1, 3);

graph.addEdge(BUTTON_2, BUTTON_3, new PadEdge(DirectionalKeypad.RIGHT));
graph.setEdgeWeight(BUTTON_2, BUTTON_3, 1);

graph.addEdge(BUTTON_2, BUTTON_5, new PadEdge(DirectionalKeypad.UP));
graph.setEdgeWeight(BUTTON_2, BUTTON_5, 2);

graph.addEdge(BUTTON_3, BUTTON_2, new PadEdge(DirectionalKeypad.LEFT));
graph.setEdgeWeight(BUTTON_3, BUTTON_2, 2);

graph.addEdge(BUTTON_3, BUTTON_6, new PadEdge(DirectionalKeypad.UP));
graph.setEdgeWeight(BUTTON_3, BUTTON_6, 1);

graph.addEdge(BUTTON_3, ACCEPT, new PadEdge(DirectionalKeypad.DOWN));
graph.setEdgeWeight(BUTTON_3, ACCEPT, 1);

graph.addEdge(BUTTON_4, BUTTON_1, new PadEdge(DirectionalKeypad.DOWN));
graph.setEdgeWeight(BUTTON_4, BUTTON_1, 3);

graph.addEdge(BUTTON_4, BUTTON_5, new PadEdge(DirectionalKeypad.RIGHT));
graph.setEdgeWeight(BUTTON_4, BUTTON_5, 2);

graph.addEdge(BUTTON_4, BUTTON_7, new PadEdge(DirectionalKeypad.UP));
graph.setEdgeWeight(BUTTON_4, BUTTON_7, 3);

graph.addEdge(BUTTON_5, BUTTON_2, new PadEdge(DirectionalKeypad.DOWN));
graph.setEdgeWeight(BUTTON_5, BUTTON_2, 2);

graph.addEdge(BUTTON_5, BUTTON_4, new PadEdge(DirectionalKeypad.LEFT));
graph.setEdgeWeight(BUTTON_5, BUTTON_4, 3);

graph.addEdge(BUTTON_5, BUTTON_6, new PadEdge(DirectionalKeypad.RIGHT));
graph.setEdgeWeight(BUTTON_5, BUTTON_6, 1);

graph.addEdge(BUTTON_5, BUTTON_8, new PadEdge(DirectionalKeypad.UP));
graph.setEdgeWeight(BUTTON_5, BUTTON_8, 2);

graph.addEdge(BUTTON_6, BUTTON_3, new PadEdge(DirectionalKeypad.DOWN));
graph.setEdgeWeight(BUTTON_6, BUTTON_3, 1);

graph.addEdge(BUTTON_6, BUTTON_5, new PadEdge(DirectionalKeypad.LEFT));
graph.setEdgeWeight(BUTTON_6, BUTTON_5, 2);

graph.addEdge(BUTTON_6, BUTTON_9, new PadEdge(DirectionalKeypad.UP));
graph.setEdgeWeight(BUTTON_6, BUTTON_9, 1);

graph.addEdge(BUTTON_7, BUTTON_4, new PadEdge(DirectionalKeypad.DOWN));
graph.setEdgeWeight(BUTTON_7, BUTTON_4, 3);

graph.addEdge(BUTTON_7, BUTTON_8, new PadEdge(DirectionalKeypad.RIGHT));
graph.setEdgeWeight(BUTTON_7, BUTTON_8, 2);

graph.addEdge(BUTTON_8, BUTTON_5, new PadEdge(DirectionalKeypad.DOWN));
graph.setEdgeWeight(BUTTON_8, BUTTON_5, 2);

graph.addEdge(BUTTON_8, BUTTON_7, new PadEdge(DirectionalKeypad.LEFT));
graph.setEdgeWeight(BUTTON_8, BUTTON_7, 3);

graph.addEdge(BUTTON_8, BUTTON_9, new PadEdge(DirectionalKeypad.RIGHT));
graph.setEdgeWeight(BUTTON_8, BUTTON_9, 1);

graph.addEdge(BUTTON_9, BUTTON_6, new PadEdge(DirectionalKeypad.DOWN));
graph.setEdgeWeight(BUTTON_9, BUTTON_6, 1);

graph.addEdge(BUTTON_9, BUTTON_8, new PadEdge(DirectionalKeypad.LEFT));
graph.setEdgeWeight(BUTTON_9, BUTTON_8, 2);
//graph.addEdge(BUTTON_9, BUTTON_2, new PadEdge(BUTTON_9_TO_BUTTON_2));

graph.addEdge(ACCEPT, BUTTON_0, new PadEdge(DirectionalKeypad.LEFT));
graph.setEdgeWeight(ACCEPT, BUTTON_0, 1);

graph.addEdge(ACCEPT, BUTTON_3, new PadEdge(DirectionalKeypad.UP));
graph.setEdgeWeight(ACCEPT, BUTTON_3, 1);


}

/// Enters a code, such as `029A`, returning a [String] representing the needed moves for it.
/// @param code the code to enter.
/// @return The String the instructions to be executed at a [DirectionalKeypad](DirectionalKeypad).
public String press(String code) {
char[] buttons = code.toCharArray();

StringBuilder sb = new StringBuilder();
for(char button : buttons) {
sb.append(press(button));
}

return sb.toString();
}

private String press(char button) {
GraphPath<Character, PadEdge> path = dijkstraShortestPath.getPath(currentKey, button);
StringBuilder sb = new StringBuilder();
for(PadEdge edge : path.getEdgeList()) {
sb.append(edge.label());
}
sb.append(ACCEPT);
currentKey = button;
return sb.toString();
}


public void reset() {
currentKey = ACCEPT;
}
}
15 changes: 15 additions & 0 deletions src/main/java/com/adventofcode/flashk/day21/PadEdge.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.adventofcode.flashk.day21;

public record PadEdge(String label, int id) {

private static int idGenerator = 0;

public PadEdge(Character label) {
this(String.valueOf(label), idGenerator++);
}

public PadEdge(String label) {
this(label, idGenerator++);
}

}
8 changes: 6 additions & 2 deletions src/test/java/com/adventofcode/flashk/day21/Day21Test.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ public void testSolvePart1Sample() {
// Read input file
List<String> inputs = Input.readStringLines(INPUT_FOLDER, TestFilename.INPUT_FILE_SAMPLE);

assertEquals(0L,0L);
KeypadConundrum keypadConundrum = new KeypadConundrum(inputs);

assertEquals(126384L, keypadConundrum.solveA());
//assertEquals(0L,keypadConundrum.solveA());
}

@Test
Expand All @@ -49,7 +52,8 @@ public void testSolvePart1Input() {
// Read input file
List<String> inputs = Input.readStringLines(INPUT_FOLDER, TestFilename.INPUT_FILE);

System.out.println("Solution: ");
KeypadConundrum keypadConundrum = new KeypadConundrum(inputs);
System.out.println("Solution: "+keypadConundrum.solveA());
assertEquals(0L,0L);

}
Expand Down
Loading

0 comments on commit 5657b04

Please sign in to comment.