Skip to content

Commit

Permalink
Solve day 19 puzzle part 1
Browse files Browse the repository at this point in the history
  • Loading branch information
Flashky committed Dec 19, 2023
1 parent 465e7c1 commit 80bc9ba
Show file tree
Hide file tree
Showing 6 changed files with 252 additions and 6 deletions.
89 changes: 89 additions & 0 deletions src/main/java/com/adventofcode/flashk/day19/Aplenty.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package com.adventofcode.flashk.day19;

import org.apache.commons.lang3.StringUtils;

import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class Aplenty {


private Map<String, Workflow> workflows = new HashMap<>();

private Map<Part,String> workflowPerPart = new LinkedHashMap<>();

public Aplenty(List<String> inputs) {

boolean readRule = true;
Iterator<String> inputsIterator = inputs.iterator();
while(inputsIterator.hasNext()) {
String input = inputsIterator.next();
if(StringUtils.isBlank(input)) {
readRule = false;
} else if (readRule) {
Workflow workflow = new Workflow(input);
workflows.put(workflow.getName(), workflow);
} else {
Part part = new Part(input);
workflowPerPart.put(part, StringUtils.EMPTY);
}
}
int a = 3;
}

public long solveA() {

Set<Part> parts = workflowPerPart.keySet();
for(Part part : parts) {
String finalWorklow = executeWorkflows(part);
workflowPerPart.put(part, finalWorklow);
}

return countAcceptedParts();
}

public long solveB() {
long result = 0;
for(int x = 1; x <= 4000; x++) {
for(int m = 1; m <= 4000; m++) {
for(int a = 1; a <= 4000; a++) {
for(int s = 1; s <= 4000; s++) {
Part part = new Part(x,m,a,s);
String finalWorkflow = executeWorkflows(part);
if(finalWorkflow.equals("A")) {
result += part.value();
//System.out.println("Part: "+part + " - Workflow: "+finalWorkflow);
}
}
}
}
}

return result;
}

public long countAcceptedParts() {
long result = 0;
Set<Part> parts = workflowPerPart.keySet();
for(Part part : parts) {
if(workflowPerPart.get(part).equals("A")) {
result += part.value();
}
}
return result;
}
private String executeWorkflows(Part part) {
Workflow workflow = workflows.get("in");
String destinationWorkflow;
do {
destinationWorkflow = workflow.run(part);
workflow = workflows.get(destinationWorkflow);
} while(workflow != null);

return destinationWorkflow;
}
}
45 changes: 45 additions & 0 deletions src/main/java/com/adventofcode/flashk/day19/Part.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.adventofcode.flashk.day19;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.ToString;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Getter
@AllArgsConstructor
@ToString
public class Part {

private static final Pattern PART_PATTERN = Pattern.compile("\\{x=(\\d*),m=(\\d*),a=(\\d*),s=(\\d*)}");

private int x;
private int m;
private int a;
private int s;

public Part(String input) {
Matcher matcher = PART_PATTERN.matcher(input);
if(matcher.find()) {
x = Integer.parseInt(matcher.group(1));
m = Integer.parseInt(matcher.group(2));
a = Integer.parseInt(matcher.group(3));
s = Integer.parseInt(matcher.group(4));
}
}

public int getRating(char letter) {
return switch (letter) {
case 'x' -> x;
case 'm' -> m;
case 'a' -> a;
case 's' -> s;
default -> throw new IllegalStateException("Unexpected value: " + letter);
};
}

public int value() {
return x+m+a+s;
}
}
52 changes: 52 additions & 0 deletions src/main/java/com/adventofcode/flashk/day19/Rule.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.adventofcode.flashk.day19;

import lombok.Getter;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Rule {

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

private static final char LESS_THAN = '<';
private static final char GREATER_THAN = '>';

private char letter;
private char condition;
private int value;

@Getter
private String destinationWorkflow;

private boolean bypassRule;

public Rule(String input) {
Matcher matcher = FULL_RULE_PATTERN.matcher(input);
if(matcher.find()) {
letter = matcher.group(1).charAt(0);
condition = matcher.group(2).charAt(0);
value = Integer.parseInt(matcher.group(3));
destinationWorkflow = matcher.group(4);
bypassRule = false;

} else {
// Direct workflow
destinationWorkflow = input;
bypassRule = true;
}
}

public boolean matches(Part part) {

if(bypassRule) {
return true;
}

if(LESS_THAN == condition) {
return part.getRating(letter) < value;
}

return part.getRating(letter) > value;
}
}
40 changes: 40 additions & 0 deletions src/main/java/com/adventofcode/flashk/day19/Workflow.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.adventofcode.flashk.day19;

import lombok.Getter;
import org.apache.commons.lang3.StringUtils;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class Workflow {

private static final Pattern NAME_PATTERN = Pattern.compile("(\\w*)\\{");

@Getter
private String name;
private List<Rule> rules;

public Workflow(String input) {
Matcher matcher = NAME_PATTERN.matcher(input);
if(matcher.find()) {
name = matcher.group(1);
}

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

public String run(Part part) {
for(Rule rule : rules) {
if(rule.matches(part)) {
return rule.getDestinationWorkflow();
}
}
return "UNKNOWN";
}
}
30 changes: 25 additions & 5 deletions src/test/java/com/adventofcode/flashk/day19/Day19Test.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@
import com.adventofcode.flashk.common.test.utils.Timer;
import com.adventofcode.flashk.common.test.utils.Input;

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

@DisplayName(TestDisplayName.DAY_19)
@TestMethodOrder(OrderAnnotation.class)
@Disabled // TODO Remove comment when implemented
public class Day19Test extends PuzzleTest {

private final static String INPUT_FOLDER = TestFolder.DAY_19;
Expand All @@ -43,7 +44,11 @@ public void testSolvePart1Sample() {

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


Aplenty aplenty = new Aplenty(inputs);
long result = aplenty.solveA();

assertEquals(19114, result);
}

@Test
Expand All @@ -57,7 +62,11 @@ public void testSolvePart1Input() {

// Read input file
List<String> inputs = Input.readStringLines(INPUT_FOLDER, TestFilename.INPUT_FILE);


Aplenty aplenty = new Aplenty(inputs);
long result = aplenty.solveA();

assertEquals(489392, result);
}

@Test
Expand All @@ -71,7 +80,11 @@ public void testSolvePart2Sample() {

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


Aplenty aplenty = new Aplenty(inputs);
long result = aplenty.solveB();

assertEquals(167409079868000L, result);
}

@Test
Expand All @@ -85,7 +98,14 @@ public void testSolvePart2Input() {

// Read input file
List<String> inputs = Input.readStringLines(INPUT_FOLDER, TestFilename.INPUT_FILE);


Aplenty aplenty = new Aplenty(inputs);
long result = aplenty.solveB();

System.out.println("R: "+result);

//assertEquals(0, result);

}

}
2 changes: 1 addition & 1 deletion src/test/resources/inputs

0 comments on commit 80bc9ba

Please sign in to comment.