Skip to content

Commit 0a305be

Browse files
committed
Non-working Day 21 revision for posterity - gonna rewrite
1 parent b79388a commit 0a305be

File tree

3 files changed

+61
-55
lines changed

3 files changed

+61
-55
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,10 @@ Once I implemented my third attempt at part 2, the only stumbling block was that
225225

226226
[On day 30] As tends to go, I had inspiration last night after I had shut everything down about how to fix this. I don't have time to work on it at the time of this writing, but I am committing the work I've done so far, even though I'm going to largely rewrite everything. One, it's bordering on unhinged, and I want to save it. :) Two...who knows, it might even come in handy later! I have seen part 2 yet, so maybe I'll get to make use of something unhinged after all. It's not a terrible commit. At least it's better than the version I was bughunting before where it turned out my numeric keypad didn't have a "1 2 3" row. :D
227227

228+
[A little later] It occurs to me that maybe I *can* salvage what I already wrote and just make it do less with a flag or something. Maybe I don't need a whole rewrite.
229+
230+
[A little later] GOD DAMN IT the algorithm wasn't the problem! I mean...it was, and still is, but it's not that the puzzle took up too much RAM, it's that I **added an extra keypad to the chain**. So...with the correct number of robots (and therefore keypads), my solution actually executes and looks like it's producing a result in the right neighborhood, but it's still wrong. It looks like whatever I was cooking up in there isn't passing test data. So *once again*, I am going to commit for posterity and then basically start over. I could halfway justify trying to salvage the unhinged implementation if it meant I could just shortcut the performance problems and get the right answer. But...I shortcut the performance problems and got the _wrong_ answer. Between that and the knowledge that the thing is already wildly overengineered for the puzzle ask, I might as well start from scratch. Sadly, I can't do it as I'm writing this, but I hope to give it another shot in the afternoon.
231+
228232
## Day 22: Monkey Market
229233

230234
I wasn't even going to start a new puzzle today, but the description for part 1 seemed so straightforward that I assumed either part 2 would be way complicated, or else I was fooling myself and part 1 would take forever with a naive implementation. I rolled the dice, though, and got part 1 relatively quickly. Then, of course, part 2 is *way* more complicated, so I'm not going to try that tonight. Until next time, monkeys!

src/com/robabrazado/aoc2024/day21/Day21Solver.java

Lines changed: 13 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,16 @@ public Day21Solver() {
1919
@Override
2020
public String solve(Stream<String> puzzleInput, boolean partOne, boolean isTest) {
2121
BigInteger result = BigInteger.ZERO;
22-
KeypadRobot myRobot = new KeypadRobot(KeypadRobot.KeypadType.DIRECTIONAL).setWorker( // I control crowded robot, who controls...
23-
new KeypadRobot(KeypadRobot.KeypadType.DIRECTIONAL).setWorker( // ...cold robot, who controls...
24-
new KeypadRobot(KeypadRobot.KeypadType.DIRECTIONAL).setWorker( // ...radiation robot, who controls...
25-
new KeypadRobot(KeypadRobot.KeypadType.NUMERIC)))); // ...vacuum robot, who controls the door.
22+
23+
KeypadRobot robotAtDepressurizedControllerAtRadiation = new KeypadRobot(KeypadRobot.KeypadType.NUMERIC);
24+
25+
KeypadRobot robotAtRadiationControllerAtFreezing = new KeypadRobot(KeypadRobot.KeypadType.DIRECTIONAL);
26+
robotAtRadiationControllerAtFreezing.setWorker(robotAtDepressurizedControllerAtRadiation);
27+
28+
KeypadRobot robotAtFreezingControllerAtCrowded = new KeypadRobot(KeypadRobot.KeypadType.DIRECTIONAL);
29+
robotAtFreezingControllerAtCrowded.setWorker(robotAtRadiationControllerAtFreezing);
30+
31+
KeypadRobot myRobot = robotAtFreezingControllerAtCrowded;
2632

2733
Iterator<String> it = puzzleInput.iterator();
2834
Pattern inputP = Pattern.compile("^(\\d+)A$");
@@ -37,40 +43,16 @@ public String solve(Stream<String> puzzleInput, boolean partOne, boolean isTest)
3743
}
3844
System.out.println("Checking base input " + baseInput);
3945

40-
// String command = myRobot.getShortestCommandForBaseInput(baseInput);
41-
String command = "SOME FOO";
46+
String command = myRobot.getShortCommandForBaseInput(baseInput);
4247
System.out.println("Found command string " + command);
4348

49+
System.out.println("Previous command string " + robotAtRadiationControllerAtFreezing.getShortCommandForBaseInput(baseInput));
50+
4451
int complexity = numericPortion * command.length();
4552
System.out.println("Complexity " + complexity);
4653
result = result.add(BigInteger.valueOf(complexity));
4754
}
4855

49-
// TESTING SHIT
50-
51-
System.out.println("---");
52-
53-
String testBaseInput = "029A";
54-
55-
KeypadRobot testNumericRobot = new KeypadRobot(KeypadRobot.KeypadType.NUMERIC);
56-
System.out.println(testNumericRobot.getShortestCommandForBaseInput(testBaseInput));
57-
58-
KeypadRobot testDirectionalRobot = new KeypadRobot(KeypadRobot.KeypadType.DIRECTIONAL);
59-
testDirectionalRobot.setWorker(testNumericRobot);
60-
System.out.println(testDirectionalRobot.getShortestCommandForBaseInput(testBaseInput));
61-
62-
KeypadRobot testDirectionalRobot2 = new KeypadRobot(KeypadRobot.KeypadType.DIRECTIONAL);
63-
testDirectionalRobot2.setWorker(testDirectionalRobot);
64-
System.out.println(testDirectionalRobot2.getShortestCommandForBaseInput(testBaseInput));
65-
66-
KeypadRobot testDirectionalRobot3 = new KeypadRobot(KeypadRobot.KeypadType.DIRECTIONAL);
67-
testDirectionalRobot3.setWorker(testDirectionalRobot2);
68-
System.out.println(testDirectionalRobot3.getShortestCommandForBaseInput(testBaseInput));
69-
70-
System.out.println("---");
71-
72-
// END TESTING
73-
7456
return result.toString();
7557

7658
}

src/com/robabrazado/aoc2024/day21/KeypadRobot.java

Lines changed: 44 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,15 @@
3939
* returning the shortest commands, on the assumption that one of the
4040
* shortest commands for me will be shortest for my controller, as well.
4141
* If that needs to change, the method signatures are already set up.
42+
*
43+
* [Much later, during part 1]
44+
*
45+
* It having been demonstrated that I WILDLY overengineered this, I had
46+
* considered starting over again, but I realized I could just basically
47+
* put a governor on this thing so the puzzle wouldn't make it keep
48+
* running out of RAM. So the structure on this is, I'm sure, all messed
49+
* up. Perhaps I'll come back to optimize...perhaps not. It will probably
50+
* depend on what part 2 of the puzzle looks like.
4251
*/
4352
public class KeypadRobot {
4453
private final KeypadType keypadType;
@@ -88,51 +97,46 @@ public KeypadRobot setWorker(KeypadRobot worker) {
8897
return this;
8998
}
9099

91-
// Assumes starting at 'A' position; terminates each button press with ACT command
92-
public String getShortestCommandForBaseInput(String input) {
93-
List<String> commands = this.getCommandsForBaseInput(input);
94-
if (commands.isEmpty()) {
95-
throw new RuntimeException("Robot has no commands for base input " + input);
96-
}
97-
return commands.get(0);
100+
// Assumes starting at 'A' position
101+
public String getShortCommandForBaseInput(String input) {
102+
return this.getShortCommandsForBaseInput(input, true).get(0);
98103
}
99104

100-
// Assumes starting at 'A' position; terminates each button press with ACT command
101-
public List<String> getCommandsForBaseInput(String input) {
105+
public List<String> getShortCommandsForBaseInput(String input, boolean exactlyOneResult) {
102106
List<String> result;
103107
if (this.worker != null) {
104-
List<String> workerCommands = worker.getCommandsForBaseInput(input);
108+
List<String> workerCommands = worker.getShortCommandsForBaseInput(input, exactlyOneResult);
105109
if (workerCommands.isEmpty()) {
106110
throw new RuntimeException("Robot's worker reports no command options for base input " + input);
107111
}
108112
result = new ArrayList<String>();
113+
/*
114+
* I think this is the part that screws me on RAM. For now, only call this
115+
* with exactlyOneResult = true.
116+
*/
109117
result = workerCommands.stream()
110118
.map(workerCommand -> this.getShortestCommandForMyInput(workerCommand))
111119
.collect(Collectors.toList());
112120
} else {
113121
// I AM BASE
114-
result = this.getCommandsForMyInput(input);
122+
result = this.getShortCommandsForMyInput(input, exactlyOneResult);
123+
Collections.sort(result, Comparator.comparingInt(String::length));
115124
}
116-
Collections.sort(result, Comparator.comparingInt(String::length));
117125
return result;
118126
}
119127

120128
// Assumes starting at 'A' position; terminates each button press with ACT command
121129
public String getShortestCommandForMyInput(String input) {
122-
List<String> commands = this.getCommandsForMyInput(input);
123-
if (commands.size() < 1) {
124-
throw new RuntimeException("Robot has no commands for this input");
125-
}
126-
return commands.get(0);
130+
return this.getShortCommandsForMyInput(input, true).get(0);
127131
}
128132

129133
// Assumes starting at 'A' position; terminates each button press with ACT command
130-
public List<String> getCommandsForMyInput(String input) {
134+
public List<String> getShortCommandsForMyInput(String input, boolean exactlyOneResult) {
131135
List<String> commands = new ArrayList<String>(Collections.singletonList(""));
132136
char[] chars = input.toCharArray();
133137
char from = 'A';
134138
for (char to : chars) {
135-
List<String> newCommands = this.getCommandsForMyInput(from, to, true);
139+
List<String> newCommands = this.getShortCommandsForMyInput(from, to, exactlyOneResult);
136140
if (newCommands.isEmpty()) {
137141
throw new RuntimeException("Robot found no command string from " + from + " to " + to);
138142
}
@@ -149,9 +153,14 @@ public List<String> getCommandsForMyInput(String input) {
149153
return commands;
150154
}
151155

152-
public List<String> getCommandsForMyInput(char from, char to, boolean terminateWithAct) {
156+
public String getShortCommandForMyInput(char from, char to) {
157+
return this.getShortCommandsForMyInput(from, to, true).get(0);
158+
}
159+
160+
// Due to my bad decisions, calling with "exactly one result" flag always skips caching; maybe fix later
161+
public List<String> getShortCommandsForMyInput(char from, char to, boolean exactlyOneResult) {
153162
CharPair pair = new CharPair(from, to);
154-
if (!this.myCommandCache.containsKey(pair)) {
163+
if (!this.myCommandCache.containsKey(pair) || exactlyOneResult) {
155164
List<String> commands = new ArrayList<String>();
156165

157166
this.checkKey(from);
@@ -211,10 +220,21 @@ public List<String> getCommandsForMyInput(char from, char to, boolean terminateW
211220
colCount <= maxColOffset && rowCount <= maxRowOffset;
212221
}
213222
if (canUse) {
214-
if (terminateWithAct) {
215-
strb.append(Command.ACT.c);
223+
// All my command strings terminate with ACT
224+
commands.add(strb.append(Command.ACT.c).toString());
225+
if (exactlyOneResult) {
226+
break;
216227
}
217-
commands.add(strb.toString());
228+
}
229+
}
230+
231+
// HEADS UP: early exit
232+
if (exactlyOneResult) {
233+
if (commands.size() == 1) {
234+
return commands;
235+
} else {
236+
throw new RuntimeException(String.format("Robot was asked for 1 result but produced %d; from '%c' to '%c'",
237+
commands.size(), from, to));
218238
}
219239
}
220240
} else {

0 commit comments

Comments
 (0)