Skip to content

Commit 020d394

Browse files
committed
Prepare day 19 part 2
1 parent bf24fa0 commit 020d394

File tree

3 files changed

+529
-3
lines changed

3 files changed

+529
-3
lines changed
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
package com.adventofcode.flashk.day19;
2+
3+
import lombok.Getter;
4+
5+
@Getter
6+
public class Range {
7+
8+
private static final int DEFAULT_MIN = 1;
9+
private static final int DEFAULT_MAX = 4000;
10+
private int minX = DEFAULT_MIN;
11+
private int maxX = DEFAULT_MAX;
12+
private int minM = DEFAULT_MIN;
13+
private int maxM = DEFAULT_MAX;
14+
private int minA = DEFAULT_MIN;
15+
private int maxA = DEFAULT_MAX;
16+
private int minS = DEFAULT_MIN;
17+
private int maxS = DEFAULT_MAX;
18+
19+
public Range() {
20+
}
21+
22+
public Range(Range other) {
23+
minX = other.minX;
24+
maxX = other.maxX;
25+
minM = other.minM;
26+
maxM = other.maxM;
27+
minA = other.minA;
28+
maxA = other.maxA;
29+
minS = other.minS;
30+
maxS = other.maxS;
31+
}
32+
33+
public long value() {
34+
long value = 0;
35+
for(int x = minX; x <= maxX; x++) {
36+
for(int m = minM; m <= maxM; m++) {
37+
for(int a = minA; a <= maxA; a++) {
38+
for(int s = minS; s <= maxS; s++) {
39+
value += x+m+a+s;
40+
}
41+
}
42+
}
43+
}
44+
return value;
45+
}
46+
47+
/**
48+
* Creates a new range that matches the rule passed as a parameter.
49+
* @param rule the rule to check
50+
* @return a new range that matches the rule
51+
*/
52+
public Range matchesRange(Rule rule) {
53+
54+
if(rule.isBypassRule()) {
55+
return this;
56+
}
57+
58+
return switch (rule.getLetter()) {
59+
case 'x' -> splitByXMatch(rule);
60+
case 'm' -> splitByMMatch(rule);
61+
case 'a' -> splitByAMatch(rule);
62+
case 's' -> splitBySMatch(rule);
63+
default -> throw new IllegalArgumentException("Invalid letter: '"+rule.getLetter()+"'");
64+
};
65+
}
66+
67+
/**
68+
* Creates a new range that does not match the rule passed as a parameter.
69+
* @param rule the rule to check
70+
* @return a new range that does not match the rule
71+
*/
72+
public Range unmatchedRange(Rule rule) {
73+
74+
if(rule.isBypassRule()) {
75+
return this;
76+
}
77+
78+
return switch (rule.getLetter()) {
79+
case 'x' -> splitByXNoMatch(rule);
80+
case 'm' -> splitByMNoMatch(rule);
81+
case 'a' -> splitByANoMatch(rule);
82+
case 's' -> splitBySNoMatch(rule);
83+
default -> throw new IllegalArgumentException("Invalid letter: '"+rule.getLetter()+"'");
84+
};
85+
}
86+
87+
private Range splitByXMatch(Rule rule) {
88+
89+
Range splitRange = new Range(this);
90+
if(rule.getCondition() == Rule.LESS_THAN) {
91+
splitRange.maxX = rule.getValue()-1;
92+
} else {
93+
splitRange.minX = rule.getValue()+1;
94+
}
95+
return splitRange;
96+
}
97+
98+
private Range splitByMMatch(Rule rule) {
99+
100+
Range splitRange = new Range(this);
101+
if(rule.getCondition() == Rule.LESS_THAN) {
102+
splitRange.maxM = rule.getValue()-1;
103+
} else {
104+
splitRange.minM = rule.getValue()+1;
105+
}
106+
return splitRange;
107+
}
108+
109+
private Range splitByAMatch(Rule rule) {
110+
111+
Range splitRange = new Range(this);
112+
if(rule.getCondition() == Rule.LESS_THAN) {
113+
splitRange.maxA = rule.getValue()-1;
114+
} else {
115+
splitRange.minA = rule.getValue()+1;
116+
}
117+
return splitRange;
118+
}
119+
120+
private Range splitBySMatch(Rule rule) {
121+
122+
Range splitRange = new Range(this);
123+
if(rule.getCondition() == Rule.LESS_THAN) {
124+
splitRange.maxS = rule.getValue()-1;
125+
} else {
126+
splitRange.minS = rule.getValue()+1;
127+
}
128+
return splitRange;
129+
}
130+
131+
private Range splitByXNoMatch(Rule rule) {
132+
133+
Range splitRange = new Range(this);
134+
if(rule.getCondition() == Rule.LESS_THAN) {
135+
splitRange.minX = rule.getValue();
136+
} else {
137+
splitRange.maxX = rule.getValue();
138+
}
139+
return splitRange;
140+
}
141+
142+
private Range splitByMNoMatch(Rule rule) {
143+
144+
Range splitRange = new Range(this);
145+
if(rule.getCondition() == Rule.LESS_THAN) {
146+
splitRange.minM = rule.getValue();
147+
} else {
148+
splitRange.maxM = rule.getValue();
149+
}
150+
return splitRange;
151+
}
152+
153+
private Range splitByANoMatch(Rule rule) {
154+
155+
Range splitRange = new Range(this);
156+
if(rule.getCondition() == Rule.LESS_THAN) {
157+
splitRange.minA = rule.getValue();
158+
} else {
159+
splitRange.maxA = rule.getValue();
160+
}
161+
return splitRange;
162+
}
163+
164+
private Range splitBySNoMatch(Rule rule) {
165+
166+
Range splitRange = new Range(this);
167+
if(rule.getCondition() == Rule.LESS_THAN) {
168+
splitRange.minS = rule.getValue();
169+
} else {
170+
splitRange.maxS = rule.getValue();
171+
}
172+
return splitRange;
173+
}
174+
}

src/main/java/com/adventofcode/flashk/day19/Rule.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,17 @@
55
import java.util.regex.Matcher;
66
import java.util.regex.Pattern;
77

8+
@Getter
89
public class Rule {
910

1011
private static final Pattern FULL_RULE_PATTERN = Pattern.compile("([xmas])([><])(\\d*):(\\w*)");
1112

12-
private static final char LESS_THAN = '<';
13+
public static final char LESS_THAN = '<';
1314

1415
private char letter;
1516
private char condition;
1617
private int value;
1718

18-
@Getter
1919
private String destinationWorkflow;
2020

2121
private boolean bypassRule;
@@ -48,4 +48,15 @@ public boolean matches(Part part) {
4848

4949
return part.getRating(letter) > value;
5050
}
51-
}
51+
52+
// Part 2
53+
// https://www.reddit.com/r/adventofcode/comments/18mdnfj/2023_day_19_part_2_how_should_i_think_about_this/
54+
55+
public Range matches(Range initialRange) {
56+
return initialRange.matchesRange(this);
57+
}
58+
59+
public Range unmatches(Range initialRange) {
60+
return initialRange.unmatchedRange(this);
61+
}
62+
}

0 commit comments

Comments
 (0)