Skip to content

Commit 931dda5

Browse files
committed
Implemented 2017 Day 25
1 parent a88c166 commit 931dda5

File tree

1 file changed

+108
-50
lines changed
  • src/main/java/com/sbaars/adventofcode/year17/days

1 file changed

+108
-50
lines changed

src/main/java/com/sbaars/adventofcode/year17/days/Day25.java

Lines changed: 108 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -2,77 +2,135 @@
22

33
import com.sbaars.adventofcode.year17.Day2017;
44
import java.util.*;
5-
import java.util.regex.*;
5+
import java.util.regex.Matcher;
6+
import java.util.regex.Pattern;
67

78
public class Day25 extends Day2017 {
8-
private enum Direction { LEFT, RIGHT }
9-
10-
private static class Rule {
11-
final int writeValue;
12-
final Direction moveDirection;
13-
final char nextState;
14-
15-
Rule(int writeValue, Direction moveDirection, char nextState) {
16-
this.writeValue = writeValue;
17-
this.moveDirection = moveDirection;
18-
this.nextState = nextState;
19-
}
20-
}
21-
22-
private final Map<Character, Map<Integer, Rule>> states = new HashMap<>();
23-
private final char initialState;
24-
private final int steps;
25-
9+
private record StateRule(int writeValue, int moveDirection, char nextState) {}
10+
private record State(StateRule zeroRule, StateRule oneRule) {}
11+
2612
public Day25() {
2713
super(25);
28-
List<String> input = dayStream().toList();
29-
initialState = input.get(0).charAt(15);
30-
steps = Integer.parseInt(input.get(1).replaceAll("\\D+", ""));
14+
}
15+
16+
public static void main(String[] args) {
17+
new Day25().printParts();
18+
}
19+
20+
private Map<Character, State> parseStates() {
21+
String[] lines = dayStrings();
22+
Map<Character, State> states = new HashMap<>();
3123

32-
for (int i = 3; i < input.size(); i++) {
33-
if (input.get(i).startsWith("In state")) {
34-
char state = input.get(i).charAt(9);
35-
Map<Integer, Rule> stateRules = new HashMap<>();
36-
24+
Pattern statePattern = Pattern.compile("In state ([A-Z]):");
25+
Pattern valuePattern = Pattern.compile("If the current value is ([01]):");
26+
Pattern writePattern = Pattern.compile("- Write the value ([01]).");
27+
Pattern movePattern = Pattern.compile("- Move one slot to the (right|left).");
28+
Pattern nextPattern = Pattern.compile("- Continue with state ([A-Z]).");
29+
30+
int i = 2; // Skip first two lines
31+
while (i < lines.length) {
32+
if (lines[i].trim().isEmpty()) {
33+
i++;
34+
continue;
35+
}
36+
37+
Matcher stateMatcher = statePattern.matcher(lines[i]);
38+
if (stateMatcher.find()) {
39+
char stateName = stateMatcher.group(1).charAt(0);
40+
StateRule[] rules = new StateRule[2];
41+
3742
for (int value = 0; value <= 1; value++) {
38-
i += 2;
39-
int writeValue = Character.getNumericValue(input.get(i).charAt(input.get(i).length() - 2));
4043
i++;
41-
Direction direction = input.get(i).contains("right") ? Direction.RIGHT : Direction.LEFT;
44+
Matcher valueMatcher = valuePattern.matcher(lines[i]);
45+
if (!valueMatcher.find() || Integer.parseInt(valueMatcher.group(1)) != value) {
46+
throw new IllegalStateException("Invalid value line: " + lines[i]);
47+
}
48+
49+
i++;
50+
Matcher writeMatcher = writePattern.matcher(lines[i]);
51+
if (!writeMatcher.find()) {
52+
throw new IllegalStateException("Invalid write line: " + lines[i]);
53+
}
54+
int writeValue = Integer.parseInt(writeMatcher.group(1));
55+
4256
i++;
43-
char nextState = input.get(i).charAt(input.get(i).length() - 2);
44-
stateRules.put(value, new Rule(writeValue, direction, nextState));
57+
Matcher moveMatcher = movePattern.matcher(lines[i]);
58+
if (!moveMatcher.find()) {
59+
throw new IllegalStateException("Invalid move line: " + lines[i]);
60+
}
61+
int moveDirection = moveMatcher.group(1).equals("right") ? 1 : -1;
62+
63+
i++;
64+
Matcher nextMatcher = nextPattern.matcher(lines[i]);
65+
if (!nextMatcher.find()) {
66+
throw new IllegalStateException("Invalid next state line: " + lines[i]);
67+
}
68+
char nextState = nextMatcher.group(1).charAt(0);
69+
70+
rules[value] = new StateRule(writeValue, moveDirection, nextState);
4571
}
46-
47-
states.put(state, stateRules);
72+
73+
states.put(stateName, new State(rules[0], rules[1]));
74+
i++;
75+
} else {
76+
i++;
4877
}
4978
}
79+
80+
return states;
5081
}
51-
52-
public static void main(String[] args) {
53-
new Day25().printParts();
82+
83+
private int getSteps() {
84+
String firstLine = dayStrings()[1];
85+
Pattern stepsPattern = Pattern.compile("Perform a diagnostic checksum after (\\d+) steps.");
86+
Matcher stepsMatcher = stepsPattern.matcher(firstLine);
87+
if (!stepsMatcher.find()) {
88+
throw new IllegalStateException("Invalid steps line: " + firstLine);
89+
}
90+
return Integer.parseInt(stepsMatcher.group(1));
5491
}
55-
92+
93+
private char getInitialState() {
94+
String firstLine = dayStrings()[0];
95+
Pattern statePattern = Pattern.compile("Begin in state ([A-Z]).");
96+
Matcher stateMatcher = statePattern.matcher(firstLine);
97+
if (!stateMatcher.find()) {
98+
throw new IllegalStateException("Invalid initial state line: " + firstLine);
99+
}
100+
return stateMatcher.group(1).charAt(0);
101+
}
102+
56103
@Override
57104
public Object part1() {
58-
Map<Integer, Integer> tape = new HashMap<>();
105+
Map<Character, State> states = parseStates();
106+
int steps = getSteps();
107+
char currentState = getInitialState();
108+
109+
// Use a TreeSet to store positions of 1s (tape is infinite with 0s by default)
110+
Set<Integer> tape = new TreeSet<>();
59111
int cursor = 0;
60-
char currentState = initialState;
61-
112+
62113
for (int i = 0; i < steps; i++) {
63-
int currentValue = tape.getOrDefault(cursor, 0);
64-
Rule rule = states.get(currentState).get(currentValue);
65-
66-
tape.put(cursor, rule.writeValue);
67-
cursor += (rule.moveDirection == Direction.RIGHT) ? 1 : -1;
68-
currentState = rule.nextState;
114+
State state = states.get(currentState);
115+
boolean currentValue = tape.contains(cursor);
116+
StateRule rule = currentValue ? state.oneRule() : state.zeroRule();
117+
118+
if (rule.writeValue() == 1) {
119+
tape.add(cursor);
120+
} else {
121+
tape.remove(cursor);
122+
}
123+
124+
cursor += rule.moveDirection();
125+
currentState = rule.nextState();
69126
}
70-
71-
return tape.values().stream().mapToInt(Integer::intValue).sum();
127+
128+
return tape.size();
72129
}
73-
130+
74131
@Override
75132
public Object part2() {
133+
// Part 2 is automatically solved by collecting all stars
76134
return "Merry Christmas!";
77135
}
78136
}

0 commit comments

Comments
 (0)