Skip to content

Commit ca98034

Browse files
committed
Solve day 19 part 2 puzzle
1 parent 020d394 commit ca98034

File tree

10 files changed

+140
-99
lines changed

10 files changed

+140
-99
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
- [Day 16 - The Floor Will Be Lava](https://github.com/Flashky/advent-of-code-2023/tree/master/src/main/java/com/adventofcode/flashk/day16)
2222
- [Day 17 - Clumsy Crucible](https://github.com/Flashky/advent-of-code-2023/tree/master/src/main/java/com/adventofcode/flashk/day17)
2323
- [Day 18 - Lavaduct Lagoon](https://github.com/Flashky/advent-of-code-2023/tree/master/src/main/java/com/adventofcode/flashk/day18)
24-
- [Day 19](https://github.com/Flashky/advent-of-code-2023/tree/master/src/main/java/com/adventofcode/flashk/day19)
24+
- [Day 19 - Aplenty](https://github.com/Flashky/advent-of-code-2023/tree/master/src/main/java/com/adventofcode/flashk/day19)
2525
- [Day 20](https://github.com/Flashky/advent-of-code-2023/tree/master/src/main/java/com/adventofcode/flashk/day20)
2626
- [Day 21](https://github.com/Flashky/advent-of-code-2023/tree/master/src/main/java/com/adventofcode/flashk/day21)
2727
- [Day 22](https://github.com/Flashky/advent-of-code-2023/tree/master/src/main/java/com/adventofcode/flashk/day22)
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package com.adventofcode.flashk.day19;
2+
3+
import lombok.Getter;
4+
5+
import java.util.HashMap;
6+
import java.util.Map;
7+
import java.util.regex.Matcher;
8+
import java.util.regex.Pattern;
9+
10+
@Getter
11+
public abstract class AbstractWorkflow {
12+
13+
private static final Pattern NAME_PATTERN = Pattern.compile("(\\w*)\\{");
14+
15+
protected static final Map<String,AbstractWorkflow> workflows = new HashMap<>();
16+
17+
private final String name;
18+
19+
protected AbstractWorkflow(String input) {
20+
21+
Matcher matcher = NAME_PATTERN.matcher(input);
22+
if(matcher.find()) {
23+
name = matcher.group(1);
24+
} else {
25+
name = input;
26+
}
27+
28+
workflows.putIfAbsent(name, this);
29+
}
30+
31+
public abstract long run(Part part);
32+
public abstract long run(Range partsRange);
33+
34+
public static void clearWorkflows() {
35+
workflows.clear();
36+
}
37+
}

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

Lines changed: 18 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,22 @@
22

33
import org.apache.commons.lang3.StringUtils;
44

5-
import java.util.HashMap;
5+
import java.util.ArrayList;
66
import java.util.Iterator;
7-
import java.util.LinkedHashMap;
87
import java.util.List;
9-
import java.util.Map;
10-
import java.util.Set;
118

129
public class Aplenty {
1310

11+
private AbstractWorkflow start;
12+
private final List<Part> parts = new ArrayList<>();
1413

15-
private Map<String, Workflow> workflows = new HashMap<>();
14+
public Aplenty(List<String> inputs) {
1615

17-
private Map<Part,String> workflowPerPart = new LinkedHashMap<>();
16+
AbstractWorkflow.clearWorkflows();
1817

19-
public Aplenty(List<String> inputs) {
18+
// Default workflows
19+
new WorkflowAccepted();
20+
new WorkflowRejected();
2021

2122
boolean readRule = true;
2223
Iterator<String> inputsIterator = inputs.iterator();
@@ -25,64 +26,29 @@ public Aplenty(List<String> inputs) {
2526
if(StringUtils.isBlank(input)) {
2627
readRule = false;
2728
} else if (readRule) {
28-
Workflow workflow = new Workflow(input);
29-
workflows.put(workflow.getName(), workflow);
29+
AbstractWorkflow workflow = new Workflow(input);
30+
if(workflow.getName().equals("in")) {
31+
start = workflow;
32+
}
3033
} else {
31-
Part part = new Part(input);
32-
workflowPerPart.put(part, StringUtils.EMPTY);
34+
parts.add(new Part(input));
3335
}
3436
}
35-
}
36-
37-
public long solveA() {
3837

39-
Set<Part> parts = workflowPerPart.keySet();
40-
for(Part part : parts) {
41-
String finalWorklow = executeWorkflows(part);
42-
workflowPerPart.put(part, finalWorklow);
43-
}
4438

45-
return countAcceptedParts();
4639
}
4740

48-
public long solveB() {
49-
long result = 0;
50-
for(int x = 1; x <= 4000; x++) {
51-
for(int m = 1; m <= 4000; m++) {
52-
for(int a = 1; a <= 4000; a++) {
53-
for(int s = 1; s <= 4000; s++) {
54-
Part part = new Part(x,m,a,s);
55-
String finalWorkflow = executeWorkflows(part);
56-
if(finalWorkflow.equals("A")) {
57-
result += part.value();
58-
//System.out.println("Part: "+part + " - Workflow: "+finalWorkflow);
59-
}
60-
}
61-
}
62-
}
63-
}
64-
65-
return result;
66-
}
41+
public long solveA() {
6742

68-
public long countAcceptedParts() {
6943
long result = 0;
70-
Set<Part> parts = workflowPerPart.keySet();
7144
for(Part part : parts) {
72-
if(workflowPerPart.get(part).equals("A")) {
73-
result += part.value();
74-
}
45+
result += start.run(part);
7546
}
47+
7648
return result;
7749
}
78-
private String executeWorkflows(Part part) {
79-
Workflow workflow = workflows.get("in");
80-
String destinationWorkflow;
81-
do {
82-
destinationWorkflow = workflow.run(part);
83-
workflow = workflows.get(destinationWorkflow);
84-
} while(workflow != null);
8550

86-
return destinationWorkflow;
51+
public long solveB() {
52+
return start.run(new Range());
8753
}
8854
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
# Day 19
1+
# Day 19: Aplenty
22

33
[https://adventofcode.com/2023/day/19](https://adventofcode.com/2023/day/19)

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

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ public class Range {
77

88
private static final int DEFAULT_MIN = 1;
99
private static final int DEFAULT_MAX = 4000;
10+
1011
private int minX = DEFAULT_MIN;
1112
private int maxX = DEFAULT_MAX;
1213
private int minM = DEFAULT_MIN;
@@ -30,18 +31,13 @@ public Range(Range other) {
3031
maxS = other.maxS;
3132
}
3233

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;
34+
public long size() {
35+
long sizeX = maxX - minX + 1L;
36+
long sizeM = maxM - minM + 1L;
37+
long sizeA = maxA - minA + 1L;
38+
long sizeS = maxS - minS + 1L;
39+
40+
return sizeX * sizeM * sizeA * sizeS;
4541
}
4642

4743
/**
Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,48 @@
11
package com.adventofcode.flashk.day19;
22

3-
import lombok.Getter;
43
import org.apache.commons.lang3.StringUtils;
54

65
import java.util.Arrays;
76
import java.util.List;
8-
import java.util.regex.Matcher;
9-
import java.util.regex.Pattern;
107
import java.util.stream.Collectors;
118

12-
public class Workflow {
9+
public class Workflow extends AbstractWorkflow {
1310

14-
private static final Pattern NAME_PATTERN = Pattern.compile("(\\w*)\\{");
15-
16-
@Getter
17-
private String name;
1811
private List<Rule> rules;
1912

2013
public Workflow(String input) {
21-
Matcher matcher = NAME_PATTERN.matcher(input);
22-
if(matcher.find()) {
23-
name = matcher.group(1);
24-
}
14+
super(input);
2515

2616
String rulesString = StringUtils.substringBetween(input, "{", "}");
2717
String[] rulesArray = rulesString.split(",");
2818
rules = Arrays.stream(rulesArray).map(Rule::new).collect(Collectors.toList());
29-
3019
}
3120

32-
public String run(Part part) {
21+
@Override
22+
public long run(Part part) {
3323
for(Rule rule : rules) {
3424
if(rule.matches(part)) {
35-
return rule.getDestinationWorkflow();
25+
// Redirect to workflow
26+
return workflows.get(rule.getDestinationWorkflow()).run(part);
3627
}
3728
}
38-
return "UNKNOWN";
29+
return 0;
30+
}
31+
32+
@Override
33+
public long run(Range partsRange) {
34+
long result = 0;
35+
Range matchedRange = new Range(partsRange);
36+
for(Rule rule : rules) {
37+
if(rule.isBypassRule()) {
38+
result += workflows.get(rule.getDestinationWorkflow()).run(matchedRange);
39+
} else {
40+
Range updatedMatchedRange = rule.matches(matchedRange);
41+
matchedRange = rule.unmatches(matchedRange);
42+
result += workflows.get(rule.getDestinationWorkflow()).run(updatedMatchedRange);
43+
}
44+
}
45+
46+
return result;
3947
}
4048
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.adventofcode.flashk.day19;
2+
3+
public class WorkflowAccepted extends AbstractWorkflow {
4+
5+
public WorkflowAccepted() {
6+
super("A");
7+
}
8+
9+
@Override
10+
public long run(Part part) {
11+
return part.value();
12+
}
13+
14+
@Override
15+
public long run(Range partsRange) {
16+
return partsRange.size();
17+
}
18+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.adventofcode.flashk.day19;
2+
3+
public class WorkflowRejected extends AbstractWorkflow {
4+
5+
public WorkflowRejected() {
6+
super("R");
7+
}
8+
9+
@Override
10+
public long run(Part part) {
11+
return 0;
12+
}
13+
14+
@Override
15+
public long run(Range partsRange) {
16+
return 0;
17+
}
18+
}

src/test/java/com/adventofcode/flashk/day19/Day19Test.java renamed to src/test/java/com/adventofcode/flashk/day19/Day19RefactorTest.java

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,27 @@
11
package com.adventofcode.flashk.day19;
22

3-
import java.util.List;
4-
3+
import com.adventofcode.flashk.common.test.constants.TestDisplayName;
4+
import com.adventofcode.flashk.common.test.constants.TestFilename;
5+
import com.adventofcode.flashk.common.test.constants.TestFolder;
6+
import com.adventofcode.flashk.common.test.constants.TestTag;
7+
import com.adventofcode.flashk.common.test.utils.Input;
8+
import com.adventofcode.flashk.common.test.utils.PuzzleTest;
9+
import com.adventofcode.flashk.common.test.utils.Timer;
510
import org.junit.jupiter.api.BeforeAll;
6-
import org.junit.jupiter.api.Disabled;
711
import org.junit.jupiter.api.DisplayName;
812
import org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
913
import org.junit.jupiter.api.Order;
1014
import org.junit.jupiter.api.Tag;
1115
import org.junit.jupiter.api.Test;
1216
import org.junit.jupiter.api.TestMethodOrder;
1317

14-
import com.adventofcode.flashk.common.test.constants.TestDisplayName;
15-
import com.adventofcode.flashk.common.test.constants.TestFilename;
16-
import com.adventofcode.flashk.common.test.constants.TestFolder;
17-
import com.adventofcode.flashk.common.test.constants.TestTag;
18-
import com.adventofcode.flashk.common.test.utils.PuzzleTest;
19-
import com.adventofcode.flashk.common.test.utils.Timer;
20-
import com.adventofcode.flashk.common.test.utils.Input;
18+
import java.util.List;
2119

2220
import static org.junit.jupiter.api.Assertions.assertEquals;
2321

2422
@DisplayName(TestDisplayName.DAY_19)
2523
@TestMethodOrder(OrderAnnotation.class)
26-
public class Day19Test extends PuzzleTest {
24+
public class Day19RefactorTest extends PuzzleTest {
2725

2826
private final static String INPUT_FOLDER = TestFolder.DAY_19;
2927

@@ -74,14 +72,15 @@ public void testSolvePart1Input() {
7472
@Tag(TestTag.PART_TWO)
7573
@Tag(TestTag.SAMPLE)
7674
@DisplayName(TestDisplayName.PART_TWO_SAMPLE)
77-
@Disabled
7875
public void testSolvePart2Sample() {
7976

8077
System.out.print("2 | sample | ");
8178

8279
// Read input file
8380
List<String> inputs = Input.readStringLines(INPUT_FOLDER, TestFilename.INPUT_FILE_SAMPLE);
8481

82+
// Question: How many combinations of ratings will be accepted?
83+
8584
Aplenty aplenty = new Aplenty(inputs);
8685
long result = aplenty.solveB();
8786

@@ -93,7 +92,6 @@ public void testSolvePart2Sample() {
9392
@Tag(TestTag.PART_TWO)
9493
@Tag(TestTag.INPUT)
9594
@DisplayName(TestDisplayName.PART_TWO_INPUT)
96-
@Disabled
9795
public void testSolvePart2Input() {
9896

9997
System.out.print("2 | input | ");
@@ -104,9 +102,8 @@ public void testSolvePart2Input() {
104102
Aplenty aplenty = new Aplenty(inputs);
105103
long result = aplenty.solveB();
106104

107-
System.out.println("R: "+result);
108-
109-
//assertEquals(0, result);
105+
System.out.println("R: " + result);
106+
assertEquals(134370637448305L, result);
110107

111108
}
112109

src/test/java/com/adventofcode/flashk/day19/RangeTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
class RangeTest {
88

99
@Test
10-
void value() {
10+
void valueAndSizeTest() {
1111
Range range = new Range();
1212

1313
Rule rule = new Rule("qkq{x<3:A,crn}");
@@ -23,6 +23,7 @@ void value() {
2323
Range matchedS = matchedA.matchesRange(rule);
2424

2525
assertEquals(96L, matchedS.value());
26+
assertEquals(16, matchedS.size());
2627

2728
}
2829

0 commit comments

Comments
 (0)