From 9abafdc3a239e63fc802b3b10825cbbc3ac81717 Mon Sep 17 00:00:00 2001 From: PascalWo Date: Thu, 4 Aug 2022 11:06:34 +0200 Subject: [PATCH 01/19] Initial setup for day7 --- .../adventofcode/days/day07/Day07.java | 79 ++++++++++++++ .../resources/puzzle_input/day7_input.txt | 101 ++++++++++++++++++ 2 files changed, 180 insertions(+) create mode 100644 src/main/java/org/haffson/adventofcode/days/day07/Day07.java create mode 100644 src/main/resources/puzzle_input/day7_input.txt diff --git a/src/main/java/org/haffson/adventofcode/days/day07/Day07.java b/src/main/java/org/haffson/adventofcode/days/day07/Day07.java new file mode 100644 index 0000000..bcb5c49 --- /dev/null +++ b/src/main/java/org/haffson/adventofcode/days/day07/Day07.java @@ -0,0 +1,79 @@ +package org.haffson.adventofcode.days.day07; + +import org.haffson.adventofcode.ProblemStatusEnum; +import org.haffson.adventofcode.days.Days; +import org.haffson.adventofcode.utils.FileReaders; +import org.haffson.adventofcode.utils.ProblemStatus; + +import javax.annotation.Nonnull; +import java.util.List; +import java.util.Map; + +/** + * Implementation for Day 7: The Sum of Its Parts. + */ +public class Day07 implements Days { + + /** + * The puzzle status {@code HashMap} + */ + @Nonnull + private final Map problemStatus; + @Nonnull + private final FileReaders fileReaders; + + /** + * Causes the input file to be parsed into the frequencies array ({@code frequencies}). + * + * @param fileReaders {@code @Autowired} fileReader //TODO: inject what you need + */ + public Day07(@Nonnull final FileReaders fileReaders) { + this.fileReaders = fileReaders; + this.problemStatus = ProblemStatus.getProblemStatusMap(1, 2, + ProblemStatusEnum.SOLVED, ProblemStatusEnum.SOLVED); + } + + @Override + public int getDay() { + return 7; + } + + @Nonnull + @Override + public Map getProblemStatus() { + return problemStatus; + } + + @Nonnull + @Override + public String firstPart() { + final String fileName = "src/main/resources/puzzle_input/day7_input.txt"; + final String part1Result = "Part 1 - : "; + return part1Result + calculateFirstPart(fileReaders.getInputList(fileName)); + } + + @Nonnull + @Override + public String secondPart() { + final String fileName = "src/main/resources/puzzle_input/day7_input.txt"; + final String part2Result = "Part 2 - : "; + return part2Result + calculateSecondPart(fileReaders.getInputList(fileName)); + } + + /** + * Primary method for Day 6, Part 1. + * Input: List with coordinates. + * Pattern looks like "x, y". + * Transform strings to List and finds the coordinate which claims the biggest area when it grows. + * + * @return long area of the biggest grown coordinate. + */ + private String calculateFirstPart(@Nonnull final List inputStringList) { + return null; + } + + + private long calculateSecondPart(@Nonnull final List inputStringList) { + return 0; + } +} diff --git a/src/main/resources/puzzle_input/day7_input.txt b/src/main/resources/puzzle_input/day7_input.txt new file mode 100644 index 0000000..ea20523 --- /dev/null +++ b/src/main/resources/puzzle_input/day7_input.txt @@ -0,0 +1,101 @@ +Step P must be finished before step Z can begin. +Step E must be finished before step O can begin. +Step X must be finished before step T can begin. +Step W must be finished before step V can begin. +Step K must be finished before step Y can begin. +Step C must be finished before step M can begin. +Step S must be finished before step R can begin. +Step T must be finished before step H can begin. +Step Z must be finished before step V can begin. +Step F must be finished before step L can begin. +Step V must be finished before step A can begin. +Step I must be finished before step A can begin. +Step J must be finished before step M can begin. +Step N must be finished before step Y can begin. +Step A must be finished before step B can begin. +Step H must be finished before step Q can begin. +Step Q must be finished before step O can begin. +Step D must be finished before step O can begin. +Step Y must be finished before step O can begin. +Step G must be finished before step L can begin. +Step B must be finished before step M can begin. +Step L must be finished before step U can begin. +Step M must be finished before step O can begin. +Step O must be finished before step U can begin. +Step R must be finished before step U can begin. +Step M must be finished before step U can begin. +Step Q must be finished before step U can begin. +Step K must be finished before step U can begin. +Step D must be finished before step R can begin. +Step A must be finished before step M can begin. +Step A must be finished before step Q can begin. +Step V must be finished before step Y can begin. +Step H must be finished before step G can begin. +Step P must be finished before step K can begin. +Step N must be finished before step A can begin. +Step P must be finished before step H can begin. +Step X must be finished before step Z can begin. +Step X must be finished before step K can begin. +Step Y must be finished before step U can begin. +Step F must be finished before step Q can begin. +Step W must be finished before step M can begin. +Step B must be finished before step L can begin. +Step E must be finished before step L can begin. +Step N must be finished before step O can begin. +Step I must be finished before step G can begin. +Step J must be finished before step H can begin. +Step Z must be finished before step N can begin. +Step V must be finished before step N can begin. +Step F must be finished before step B can begin. +Step A must be finished before step Y can begin. +Step Q must be finished before step R can begin. +Step L must be finished before step O can begin. +Step H must be finished before step U can begin. +Step V must be finished before step G can begin. +Step Z must be finished before step B can begin. +Step V must be finished before step J can begin. +Step V must be finished before step O can begin. +Step T must be finished before step D can begin. +Step Y must be finished before step M can begin. +Step B must be finished before step R can begin. +Step O must be finished before step R can begin. +Step C must be finished before step V can begin. +Step W must be finished before step T can begin. +Step P must be finished before step N can begin. +Step L must be finished before step R can begin. +Step V must be finished before step U can begin. +Step C must be finished before step J can begin. +Step N must be finished before step R can begin. +Step X must be finished before step S can begin. +Step X must be finished before step A can begin. +Step G must be finished before step O can begin. +Step A must be finished before step O can begin. +Step X must be finished before step O can begin. +Step D must be finished before step Y can begin. +Step C must be finished before step G can begin. +Step K must be finished before step D can begin. +Step N must be finished before step B can begin. +Step C must be finished before step B can begin. +Step W must be finished before step F can begin. +Step E must be finished before step Z can begin. +Step S must be finished before step V can begin. +Step G must be finished before step M can begin. +Step T must be finished before step B can begin. +Step W must be finished before step C can begin. +Step D must be finished before step G can begin. +Step L must be finished before step M can begin. +Step H must be finished before step D can begin. +Step G must be finished before step R can begin. +Step T must be finished before step J can begin. +Step A must be finished before step R can begin. +Step B must be finished before step O can begin. +Step J must be finished before step R can begin. +Step G must be finished before step U can begin. +Step K must be finished before step O can begin. +Step V must be finished before step L can begin. +Step M must be finished before step R can begin. +Step D must be finished before step U can begin. +Step H must be finished before step Y can begin. +Step P must be finished before step W can begin. +Step K must be finished before step I can begin. +Step J must be finished before step G can begin. From 75db863fb1b6e322ae299d31f95e90ee1c93bdfd Mon Sep 17 00:00:00 2001 From: PascalWo Date: Thu, 4 Aug 2022 11:06:44 +0200 Subject: [PATCH 02/19] First test for day7 --- .../adventofcode/days/day07/Day07Test.java | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 src/test/java/org/haffson/adventofcode/days/day07/Day07Test.java diff --git a/src/test/java/org/haffson/adventofcode/days/day07/Day07Test.java b/src/test/java/org/haffson/adventofcode/days/day07/Day07Test.java new file mode 100644 index 0000000..835a718 --- /dev/null +++ b/src/test/java/org/haffson/adventofcode/days/day07/Day07Test.java @@ -0,0 +1,56 @@ +package org.haffson.adventofcode.days.day07; + +import org.haffson.adventofcode.utils.FileReaders; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +class Day07Test { + + private Day07 day07; + + @BeforeEach + void setUp() { + final FileReaders fileReaders = mock(FileReaders.class); + day07 = new Day07(fileReaders); + + when(fileReaders.getInputList("src/main/resources/puzzle_input/day7_input.txt")) + .thenReturn(List.of( + "Step C must be finished before step A can begin.", + "Step C must be finished before step F can begin.", + "Step A must be finished before step B can begin.", + "Step A must be finished before step D can begin.", + "Step B must be finished before step E can begin.", + "Step D must be finished before step E can begin.", + "Step F must be finished before step E can begin." + )); + } + + @DisplayName("get the current AoC Day") + @Test + void testGetDay() { + final int expectedResult = 7; + final int actualResult = day07.getDay(); + assertThat(actualResult).isEqualTo(expectedResult); + } + + @DisplayName("First part - should return correct order of steps") + @Test + void test_firstPart_returnsExpectedResult() { + //arrange + final String expectedResult = "Part 1 - : " + "CABDFE"; + + //act + final String actualResult = day07.firstPart(); + + //assert + assertThat(actualResult).isEqualTo(expectedResult); + } + +} From ed4cf1c196bb47b149ee61dfc440e5335f02e264 Mon Sep 17 00:00:00 2001 From: PascalWo Date: Wed, 10 Aug 2022 11:54:30 +0200 Subject: [PATCH 03/19] First Solution for day7 --- .../adventofcode/days/day07/Day07.java | 15 +- .../days/day07/StepInstruction.java | 37 ++++ .../adventofcode/days/day07/StepSorter.java | 199 ++++++++++++++++++ .../days/day07/StepInstructionTest.java | 41 ++++ .../days/day07/StepSorterTest.java | 54 +++++ 5 files changed, 340 insertions(+), 6 deletions(-) create mode 100644 src/main/java/org/haffson/adventofcode/days/day07/StepInstruction.java create mode 100644 src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java create mode 100644 src/test/java/org/haffson/adventofcode/days/day07/StepInstructionTest.java create mode 100644 src/test/java/org/haffson/adventofcode/days/day07/StepSorterTest.java diff --git a/src/main/java/org/haffson/adventofcode/days/day07/Day07.java b/src/main/java/org/haffson/adventofcode/days/day07/Day07.java index bcb5c49..9003840 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/Day07.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/Day07.java @@ -4,6 +4,7 @@ import org.haffson.adventofcode.days.Days; import org.haffson.adventofcode.utils.FileReaders; import org.haffson.adventofcode.utils.ProblemStatus; +import org.springframework.stereotype.Component; import javax.annotation.Nonnull; import java.util.List; @@ -12,6 +13,7 @@ /** * Implementation for Day 7: The Sum of Its Parts. */ +@Component public class Day07 implements Days { /** @@ -61,15 +63,16 @@ public String secondPart() { } /** - * Primary method for Day 6, Part 1. - * Input: List with coordinates. - * Pattern looks like "x, y". - * Transform strings to List and finds the coordinate which claims the biggest area when it grows. + * Primary method for Day 7, Part 1. * - * @return long area of the biggest grown coordinate. + * @return sorted String of Steps. */ + @Nonnull private String calculateFirstPart(@Nonnull final List inputStringList) { - return null; + final List inputList = StepInstruction.of(inputStringList); + final StepSorter stepSorter = new StepSorter(inputList); + + return stepSorter.getSortedSteps(); } diff --git a/src/main/java/org/haffson/adventofcode/days/day07/StepInstruction.java b/src/main/java/org/haffson/adventofcode/days/day07/StepInstruction.java new file mode 100644 index 0000000..0b24799 --- /dev/null +++ b/src/main/java/org/haffson/adventofcode/days/day07/StepInstruction.java @@ -0,0 +1,37 @@ +package org.haffson.adventofcode.days.day07; + +import javax.annotation.Nonnull; +import java.util.List; + +public record StepInstruction(char step, char finishedBefore) { + + @Nonnull + public static StepInstruction of(@Nonnull final String input) { + final String[] split1 = input.split(" "); + final char step = split1[1].charAt(0); + final char finishedBefore = split1[7].charAt(0); + + return new StepInstruction(step, finishedBefore); + } + + @Nonnull + public static List of(@Nonnull final List inputList) { + return inputList.stream().map(StepInstruction::of).toList(); + } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + final StepInstruction that = (StepInstruction) o; + return step == that.step && finishedBefore == that.finishedBefore; + } + + @Override + public String toString() { + return "StepInstruction{" + + "step=" + step + + ", finishedBefore=" + finishedBefore + + '}'; + } +} diff --git a/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java b/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java new file mode 100644 index 0000000..439c406 --- /dev/null +++ b/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java @@ -0,0 +1,199 @@ +package org.haffson.adventofcode.days.day07; + +import javax.annotation.Nonnull; +import java.util.*; + +public class StepSorter { + + private final List stepInstructions; + + private List startingStep; + + private List availableStepInstructions = new ArrayList<>(); + private List availableStepInstructionsNotUsed = new ArrayList<>(); + private StepInstruction nextStepInstruction; + private char stepWhenInstructionIsEmpty; + + private char stepWhenInstructionIsDuplicated; + + private char leastStep; + + public List getStartingStep() { + return startingStep; + } + + + List resultString = new ArrayList<>(); + + public StepSorter(final List stepInstructions) { + this.stepInstructions = stepInstructions; + } + + + public String getSortedSteps() { + char stepToCheck; + + findStartingStep(); + + checkStarterAvailable(); + + resultString.add(startingStep.get(0)); + + stepToCheck = startingStep.get(0); + + for (int i = 0; i < stepInstructions.size(); i++) { + setAvailableStepInstructions(stepToCheck); + + getNextStepInstructionByAlphabeticalOrder(); + + if (nextStepInstruction != null) { + stepToCheck = nextStepInstruction.finishedBefore(); + + if (stepToCheck == leastStep) { + setNextStepWhenDuplicate(); + stepToCheck = stepWhenInstructionIsDuplicated; + } + } else { + setNextStepWhenEmpty(); + stepToCheck = stepWhenInstructionIsEmpty; + } + + + if (!resultString.contains(stepToCheck)) { + resultString.add(stepToCheck); + leastStep = stepToCheck; + } + } + + return getStringRepresentation(resultString); + } + + @Nonnull + private String getStringRepresentation(@Nonnull final List list) { + final StringBuilder builder = new StringBuilder(list.size()); + for (final Character character : list) { + builder.append(character); + } + return builder.toString(); + } + + public void findStartingStep() { + final List steps = new ArrayList<>(); + this.stepInstructions.forEach(stepInstruction -> steps.add(stepInstruction.step())); + + final List stepsFinishedBefore = new ArrayList<>(); + this.stepInstructions.forEach(stepInstruction -> stepsFinishedBefore.add(stepInstruction.finishedBefore())); + + final List stepsWithoutPreCondition = new ArrayList<>(steps); + stepsWithoutPreCondition.removeAll(stepsFinishedBefore); + final Set stepsWithoutPreConditionDuplicateFree = new HashSet<>(stepsWithoutPreCondition); + + + this.startingStep = new ArrayList<>(stepsWithoutPreConditionDuplicateFree); + } + + public void checkStarterAvailable() { + for (final char stepToCompare : startingStep) { + availableStepInstructionsNotUsed.addAll(getAvailableStepInstructions(stepToCompare)); + } + } + + private void setAvailableStepInstructions(final char stepToCompare) { + final Set availableInstructions = new HashSet<>(); + + availableInstructions.addAll(getAvailableStepInstructions(stepToCompare)); + availableInstructions.addAll(availableStepInstructionsNotUsed); + + this.availableStepInstructions = new ArrayList<>(availableInstructions); + } + + @Nonnull + private List getAvailableStepInstructions(final char stepToCompare) { + return List.copyOf(stepInstructions).stream() + .filter(stepInstruction -> stepToCompare == stepInstruction.step()). + toList(); + } + + private void getNextStepInstructionByAlphabeticalOrder() { + sortInstructionsAlphabeticalByFinishedBefore(); + for (int i = 0; i < availableStepInstructions.size(); i++) { + if (isNextStepInstruction(i)) { + setNextStepInstruction(i); + setUnusedStepInstructions(i); + break; + } + } + } + + private boolean isNextStepInstruction(final int i) { + final StepInstruction possibleNextInstruction = availableStepInstructions.get(i); + + return isPrerequisiteComplete(possibleNextInstruction); + } + + private void setNextStepInstruction(final int i) { + this.nextStepInstruction = availableStepInstructions.get(i); + } + + private void setUnusedStepInstructions(final int i) { + final List stepInstructionsNotUsed = new ArrayList<>(availableStepInstructions); + stepInstructionsNotUsed.remove(i); + this.availableStepInstructionsNotUsed = stepInstructionsNotUsed; + } + + + private void setNextStepWhenEmpty() { + this.stepWhenInstructionIsEmpty = getAvailableStarterSteps().get(0); + } + + private void setNextStepWhenDuplicate() { + if (!getAvailableStarterSteps().isEmpty()) { + this.stepWhenInstructionIsDuplicated = getAvailableStarterSteps().get(0); + } + } + + @Nonnull + private List getAvailableStarterSteps() { + final List starterSteps = new ArrayList<>(startingStep); + final List actualSteps = new ArrayList<>(resultString); + + starterSteps.removeAll(actualSteps); + + return starterSteps; + } + + private void sortInstructionsAlphabeticalByFinishedBefore() { + this.availableStepInstructions = availableStepInstructions + .stream() + .sorted(Comparator.comparing(StepInstruction::finishedBefore)) + .toList(); + } + + private boolean isPrerequisiteComplete(@Nonnull final StepInstruction toCheck) { + final char stepToCheck = toCheck.finishedBefore(); + + if (stepIsAlreadyUsed(stepToCheck)) { + return false; + } + final List stepsNeededToBeCompleted = getStepsNeedToBeCompleted(stepToCheck); + + return isEveryNeededStepCompleted(stepsNeededToBeCompleted); + } + + private boolean stepIsAlreadyUsed(final char stepToCheck) { + return resultString.contains(stepToCheck); + } + + @Nonnull + private List getStepsNeedToBeCompleted(final char stepToCheck) { + return List.copyOf(stepInstructions) + .stream() + .filter(stepInstruction -> stepToCheck == stepInstruction.finishedBefore()) + .map(StepInstruction::step) + .toList(); + } + + private boolean isEveryNeededStepCompleted(@Nonnull final List stepsNeededToBeCompleted) { + return new HashSet<>(resultString).containsAll(stepsNeededToBeCompleted); + } +} diff --git a/src/test/java/org/haffson/adventofcode/days/day07/StepInstructionTest.java b/src/test/java/org/haffson/adventofcode/days/day07/StepInstructionTest.java new file mode 100644 index 0000000..c6fcabe --- /dev/null +++ b/src/test/java/org/haffson/adventofcode/days/day07/StepInstructionTest.java @@ -0,0 +1,41 @@ +package org.haffson.adventofcode.days.day07; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +class StepInstructionTest { + + @DisplayName("of() should return new StepInstruction") + @Test + void of_returnStepInstruction() { + //arrange + final String input = "Step C must be finished before step A can begin."; + final StepInstruction expectedResult = new StepInstruction('C', 'A'); + //act + final StepInstruction actualResult = StepInstruction.of(input); + //assert + assertThat(actualResult).isEqualTo(expectedResult); + } + + @DisplayName("of() should return list of new StepInstruction") + @Test + void of_returnStepInstructionList() { + //arrange + final String input1 = "Step C must be finished before step A can begin."; + final String input2 = "Step C must be finished before step F can begin."; + final String input3 = "Step A must be finished before step B can begin."; + + final List inputList = List.of(input1, input2, input3); + final List expectedResult = List.of(new StepInstruction('C', 'A'), + new StepInstruction('C', 'F'), + new StepInstruction('A', 'B')); + //act + final List actualResult = StepInstruction.of(inputList); + //assert + assertThat(actualResult).isEqualTo(expectedResult); + } +} diff --git a/src/test/java/org/haffson/adventofcode/days/day07/StepSorterTest.java b/src/test/java/org/haffson/adventofcode/days/day07/StepSorterTest.java new file mode 100644 index 0000000..0a460f4 --- /dev/null +++ b/src/test/java/org/haffson/adventofcode/days/day07/StepSorterTest.java @@ -0,0 +1,54 @@ +package org.haffson.adventofcode.days.day07; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +class StepSorterTest { + + @BeforeEach + void setUp() { + + } + + @DisplayName("find starting step character") + @Test + void findStartingStep_shouldReturnStartingStep() { + //arrange + final List stepInstructions = List.of(new StepInstruction('C', 'A'), + new StepInstruction('C', 'F'), + new StepInstruction('A', 'B')); + final StepSorter stepSorter = new StepSorter(stepInstructions); + final List expectedResult = List.of('C'); + //act + stepSorter.findStartingStep(); + final List actualResult = stepSorter.getStartingStep(); + //assert + assertThat(actualResult).isEqualTo(expectedResult); + } + + @Test + void getSortedSteps_shouldReturnSortedStepsAsString() { + //arrange + final List stepInstructions = List.of(new StepInstruction('C', 'A'), + new StepInstruction('C', 'F'), + new StepInstruction('A', 'B'), + new StepInstruction('A', 'D'), + new StepInstruction('B', 'E'), + new StepInstruction('D', 'E'), + new StepInstruction('F', 'E')); + + final StepSorter stepSorter = new StepSorter(stepInstructions); + + final String expectedResult = "CABDFE"; + //act + + final String actualResult = stepSorter.getSortedSteps(); + //assert + assertThat(actualResult).isEqualTo(expectedResult); + } +} From ad6b573f024a72bcf0aca24d4ced1358e63dcab7 Mon Sep 17 00:00:00 2001 From: PascalWo Date: Wed, 10 Aug 2022 15:13:18 +0200 Subject: [PATCH 04/19] Refactoring --- .../adventofcode/days/day07/StepSorter.java | 108 ++++++++++-------- .../days/day07/StepSorterTest.java | 2 +- 2 files changed, 63 insertions(+), 47 deletions(-) diff --git a/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java b/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java index 439c406..4ba5ee5 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java @@ -5,12 +5,14 @@ public class StepSorter { + @Nonnull private final List stepInstructions; - - private List startingStep; - + private List startingSteps; + @Nonnull private List availableStepInstructions = new ArrayList<>(); + @Nonnull private List availableStepInstructionsNotUsed = new ArrayList<>(); + private StepInstruction nextStepInstruction; private char stepWhenInstructionIsEmpty; @@ -18,63 +20,77 @@ public class StepSorter { private char leastStep; - public List getStartingStep() { - return startingStep; - } + private char nextStepToCheck; + private final List resultAsCharList = new ArrayList<>(); - List resultString = new ArrayList<>(); - - public StepSorter(final List stepInstructions) { + public StepSorter(@Nonnull final List stepInstructions) { this.stepInstructions = stepInstructions; } public String getSortedSteps() { - char stepToCheck; + initialiseStarting(); - findStartingStep(); + for (int i = 0; i < stepInstructions.size(); i++) { + setAvailableStepInstructions(nextStepToCheck); - checkStarterAvailable(); + getNextStepInstructionByAlphabeticalOrder(); - resultString.add(startingStep.get(0)); + setNextStepToCheck(); - stepToCheck = startingStep.get(0); + addStepToResult(); + } - for (int i = 0; i < stepInstructions.size(); i++) { - setAvailableStepInstructions(stepToCheck); + return getResultAsString(resultAsCharList); + } - getNextStepInstructionByAlphabeticalOrder(); + public List getStartingSteps() { + return startingSteps; + } - if (nextStepInstruction != null) { - stepToCheck = nextStepInstruction.finishedBefore(); + private char getStartingStep() { + return startingSteps.get(0); + } - if (stepToCheck == leastStep) { - setNextStepWhenDuplicate(); - stepToCheck = stepWhenInstructionIsDuplicated; - } - } else { - setNextStepWhenEmpty(); - stepToCheck = stepWhenInstructionIsEmpty; + private void setNextStepToCheck() { + if (nextStepInstruction != null) { + this.nextStepToCheck = nextStepInstruction.finishedBefore(); + if (nextStepToCheck == leastStep) { + setNextStepWhenDuplicate(); + this.nextStepToCheck = stepWhenInstructionIsDuplicated; } + } else { + setNextStepWhenEmpty(); + this.nextStepToCheck = stepWhenInstructionIsEmpty; + } + } - - if (!resultString.contains(stepToCheck)) { - resultString.add(stepToCheck); - leastStep = stepToCheck; - } + private void addStepToResult() { + if (!resultAsCharList.contains(nextStepToCheck)) { + this.resultAsCharList.add(nextStepToCheck); + setLeastStep(); } + } - return getStringRepresentation(resultString); + private void setLeastStep() { + this.leastStep = nextStepToCheck; + } + + private void initialiseStarting() { + findStartingStep(); + setAvailableStarterOptions(); + resultAsCharList.add(getStartingStep()); + nextStepToCheck = getStartingStep(); } @Nonnull - private String getStringRepresentation(@Nonnull final List list) { - final StringBuilder builder = new StringBuilder(list.size()); - for (final Character character : list) { - builder.append(character); + private String getResultAsString(@Nonnull final List result) { + final StringBuilder stringBuilder = new StringBuilder(result.size()); + for (final Character character : result) { + stringBuilder.append(character); } - return builder.toString(); + return stringBuilder.toString(); } public void findStartingStep() { @@ -89,11 +105,11 @@ public void findStartingStep() { final Set stepsWithoutPreConditionDuplicateFree = new HashSet<>(stepsWithoutPreCondition); - this.startingStep = new ArrayList<>(stepsWithoutPreConditionDuplicateFree); + this.startingSteps = new ArrayList<>(stepsWithoutPreConditionDuplicateFree); } - public void checkStarterAvailable() { - for (final char stepToCompare : startingStep) { + public void setAvailableStarterOptions() { + for (final char stepToCompare : startingSteps) { availableStepInstructionsNotUsed.addAll(getAvailableStepInstructions(stepToCompare)); } } @@ -154,8 +170,8 @@ private void setNextStepWhenDuplicate() { @Nonnull private List getAvailableStarterSteps() { - final List starterSteps = new ArrayList<>(startingStep); - final List actualSteps = new ArrayList<>(resultString); + final List starterSteps = new ArrayList<>(startingSteps); + final List actualSteps = new ArrayList<>(resultAsCharList); starterSteps.removeAll(actualSteps); @@ -169,8 +185,8 @@ private void sortInstructionsAlphabeticalByFinishedBefore() { .toList(); } - private boolean isPrerequisiteComplete(@Nonnull final StepInstruction toCheck) { - final char stepToCheck = toCheck.finishedBefore(); + private boolean isPrerequisiteComplete(@Nonnull final StepInstruction instructionToCheck) { + final char stepToCheck = instructionToCheck.finishedBefore(); if (stepIsAlreadyUsed(stepToCheck)) { return false; @@ -181,7 +197,7 @@ private boolean isPrerequisiteComplete(@Nonnull final StepInstruction toCheck) { } private boolean stepIsAlreadyUsed(final char stepToCheck) { - return resultString.contains(stepToCheck); + return resultAsCharList.contains(stepToCheck); } @Nonnull @@ -194,6 +210,6 @@ private List getStepsNeedToBeCompleted(final char stepToCheck) { } private boolean isEveryNeededStepCompleted(@Nonnull final List stepsNeededToBeCompleted) { - return new HashSet<>(resultString).containsAll(stepsNeededToBeCompleted); + return new HashSet<>(resultAsCharList).containsAll(stepsNeededToBeCompleted); } } diff --git a/src/test/java/org/haffson/adventofcode/days/day07/StepSorterTest.java b/src/test/java/org/haffson/adventofcode/days/day07/StepSorterTest.java index 0a460f4..ef3af3c 100644 --- a/src/test/java/org/haffson/adventofcode/days/day07/StepSorterTest.java +++ b/src/test/java/org/haffson/adventofcode/days/day07/StepSorterTest.java @@ -26,7 +26,7 @@ void findStartingStep_shouldReturnStartingStep() { final List expectedResult = List.of('C'); //act stepSorter.findStartingStep(); - final List actualResult = stepSorter.getStartingStep(); + final List actualResult = stepSorter.getStartingSteps(); //assert assertThat(actualResult).isEqualTo(expectedResult); } From ba67eb7e5e6438003fd24582dd95b19b1975bea8 Mon Sep 17 00:00:00 2001 From: PascalWo Date: Thu, 11 Aug 2022 08:28:58 +0200 Subject: [PATCH 05/19] refactored result to separat class --- .../adventofcode/days/day07/SortedSteps.java | 29 +++++++++++++++++ .../adventofcode/days/day07/StepSorter.java | 32 +++++++------------ 2 files changed, 40 insertions(+), 21 deletions(-) create mode 100644 src/main/java/org/haffson/adventofcode/days/day07/SortedSteps.java diff --git a/src/main/java/org/haffson/adventofcode/days/day07/SortedSteps.java b/src/main/java/org/haffson/adventofcode/days/day07/SortedSteps.java new file mode 100644 index 0000000..1ab44cc --- /dev/null +++ b/src/main/java/org/haffson/adventofcode/days/day07/SortedSteps.java @@ -0,0 +1,29 @@ +package org.haffson.adventofcode.days.day07; + +import javax.annotation.Nonnull; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +public class SortedSteps { + private final List stepSequence; + + public SortedSteps(){ + this.stepSequence = new ArrayList<>(); + } + + public List getStepSequence(){ + return Collections.unmodifiableList(stepSequence); + } + + public void addStep(final char nextStepToCheck) { + if (!stepSequence.contains(nextStepToCheck)) { + this.stepSequence.add(nextStepToCheck); + } + } + @Nonnull + public String getSequenceAsString() { + return stepSequence.stream().map(String::valueOf).collect(Collectors.joining()); + } +} diff --git a/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java b/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java index 4ba5ee5..72c9896 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java @@ -21,11 +21,12 @@ public class StepSorter { private char leastStep; private char nextStepToCheck; - - private final List resultAsCharList = new ArrayList<>(); + + private final SortedSteps sortedSteps; public StepSorter(@Nonnull final List stepInstructions) { this.stepInstructions = stepInstructions; + this.sortedSteps = new SortedSteps(); } @@ -42,7 +43,7 @@ public String getSortedSteps() { addStepToResult(); } - return getResultAsString(resultAsCharList); + return sortedSteps.getSequenceAsString(); } public List getStartingSteps() { @@ -67,10 +68,8 @@ private void setNextStepToCheck() { } private void addStepToResult() { - if (!resultAsCharList.contains(nextStepToCheck)) { - this.resultAsCharList.add(nextStepToCheck); - setLeastStep(); - } + sortedSteps.addStep(nextStepToCheck); + setLeastStep(); } private void setLeastStep() { @@ -80,17 +79,8 @@ private void setLeastStep() { private void initialiseStarting() { findStartingStep(); setAvailableStarterOptions(); - resultAsCharList.add(getStartingStep()); - nextStepToCheck = getStartingStep(); - } - - @Nonnull - private String getResultAsString(@Nonnull final List result) { - final StringBuilder stringBuilder = new StringBuilder(result.size()); - for (final Character character : result) { - stringBuilder.append(character); - } - return stringBuilder.toString(); + this.sortedSteps.addStep(getStartingStep()); + this.nextStepToCheck = getStartingStep(); } public void findStartingStep() { @@ -171,7 +161,7 @@ private void setNextStepWhenDuplicate() { @Nonnull private List getAvailableStarterSteps() { final List starterSteps = new ArrayList<>(startingSteps); - final List actualSteps = new ArrayList<>(resultAsCharList); + final List actualSteps = new ArrayList<>(sortedSteps.getStepSequence()); starterSteps.removeAll(actualSteps); @@ -197,7 +187,7 @@ private boolean isPrerequisiteComplete(@Nonnull final StepInstruction instructio } private boolean stepIsAlreadyUsed(final char stepToCheck) { - return resultAsCharList.contains(stepToCheck); + return sortedSteps.getStepSequence().contains(stepToCheck); } @Nonnull @@ -210,6 +200,6 @@ private List getStepsNeedToBeCompleted(final char stepToCheck) { } private boolean isEveryNeededStepCompleted(@Nonnull final List stepsNeededToBeCompleted) { - return new HashSet<>(resultAsCharList).containsAll(stepsNeededToBeCompleted); + return new HashSet<>(sortedSteps.getStepSequence()).containsAll(stepsNeededToBeCompleted); } } From ebf3609cfcff8dde655b0fcc76638367b2b05555 Mon Sep 17 00:00:00 2001 From: PascalWo Date: Thu, 11 Aug 2022 08:30:23 +0200 Subject: [PATCH 06/19] formatting --- .../org/haffson/adventofcode/days/day07/SortedSteps.java | 5 +++-- .../java/org/haffson/adventofcode/days/day07/StepSorter.java | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/haffson/adventofcode/days/day07/SortedSteps.java b/src/main/java/org/haffson/adventofcode/days/day07/SortedSteps.java index 1ab44cc..c9b0645 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/SortedSteps.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/SortedSteps.java @@ -9,11 +9,11 @@ public class SortedSteps { private final List stepSequence; - public SortedSteps(){ + public SortedSteps() { this.stepSequence = new ArrayList<>(); } - public List getStepSequence(){ + public List getStepSequence() { return Collections.unmodifiableList(stepSequence); } @@ -22,6 +22,7 @@ public void addStep(final char nextStepToCheck) { this.stepSequence.add(nextStepToCheck); } } + @Nonnull public String getSequenceAsString() { return stepSequence.stream().map(String::valueOf).collect(Collectors.joining()); diff --git a/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java b/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java index 72c9896..25cf1d2 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java @@ -21,7 +21,7 @@ public class StepSorter { private char leastStep; private char nextStepToCheck; - + private final SortedSteps sortedSteps; public StepSorter(@Nonnull final List stepInstructions) { From b42f3f66dfdb41982b8bd9beda80fd6c79a2e7fb Mon Sep 17 00:00:00 2001 From: PascalWo Date: Thu, 11 Aug 2022 08:43:37 +0200 Subject: [PATCH 07/19] added requireNonNUll --- src/main/java/org/haffson/adventofcode/days/day07/Day07.java | 4 +++- .../org/haffson/adventofcode/days/day07/StepInstruction.java | 4 ++++ .../java/org/haffson/adventofcode/days/day07/StepSorter.java | 4 +++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/haffson/adventofcode/days/day07/Day07.java b/src/main/java/org/haffson/adventofcode/days/day07/Day07.java index 9003840..bfa1e09 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/Day07.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/Day07.java @@ -10,6 +10,8 @@ import java.util.List; import java.util.Map; +import static java.util.Objects.requireNonNull; + /** * Implementation for Day 7: The Sum of Its Parts. */ @@ -30,7 +32,7 @@ public class Day07 implements Days { * @param fileReaders {@code @Autowired} fileReader //TODO: inject what you need */ public Day07(@Nonnull final FileReaders fileReaders) { - this.fileReaders = fileReaders; + this.fileReaders = requireNonNull(fileReaders, "fileReaders"); this.problemStatus = ProblemStatus.getProblemStatusMap(1, 2, ProblemStatusEnum.SOLVED, ProblemStatusEnum.SOLVED); } diff --git a/src/main/java/org/haffson/adventofcode/days/day07/StepInstruction.java b/src/main/java/org/haffson/adventofcode/days/day07/StepInstruction.java index 0b24799..a442ba3 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/StepInstruction.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/StepInstruction.java @@ -3,10 +3,13 @@ import javax.annotation.Nonnull; import java.util.List; +import static java.util.Objects.requireNonNull; + public record StepInstruction(char step, char finishedBefore) { @Nonnull public static StepInstruction of(@Nonnull final String input) { + requireNonNull(input, "input"); final String[] split1 = input.split(" "); final char step = split1[1].charAt(0); final char finishedBefore = split1[7].charAt(0); @@ -16,6 +19,7 @@ public static StepInstruction of(@Nonnull final String input) { @Nonnull public static List of(@Nonnull final List inputList) { + requireNonNull(inputList, "inputList"); return inputList.stream().map(StepInstruction::of).toList(); } diff --git a/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java b/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java index 25cf1d2..1420676 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java @@ -3,6 +3,8 @@ import javax.annotation.Nonnull; import java.util.*; +import static java.util.Objects.requireNonNull; + public class StepSorter { @Nonnull @@ -25,7 +27,7 @@ public class StepSorter { private final SortedSteps sortedSteps; public StepSorter(@Nonnull final List stepInstructions) { - this.stepInstructions = stepInstructions; + this.stepInstructions = requireNonNull(stepInstructions, "stepInstructions"); this.sortedSteps = new SortedSteps(); } From 89e7a99eb323dae5b657dac4cd88da366d991458 Mon Sep 17 00:00:00 2001 From: PascalWo Date: Mon, 22 Aug 2022 08:59:06 +0200 Subject: [PATCH 08/19] refactored to extended step class --- .../days/day07/SelectedSteps.java | 64 ++++++++ .../adventofcode/days/day07/StepSorter.java | 148 ++++++++---------- 2 files changed, 130 insertions(+), 82 deletions(-) create mode 100644 src/main/java/org/haffson/adventofcode/days/day07/SelectedSteps.java diff --git a/src/main/java/org/haffson/adventofcode/days/day07/SelectedSteps.java b/src/main/java/org/haffson/adventofcode/days/day07/SelectedSteps.java new file mode 100644 index 0000000..9668108 --- /dev/null +++ b/src/main/java/org/haffson/adventofcode/days/day07/SelectedSteps.java @@ -0,0 +1,64 @@ +package org.haffson.adventofcode.days.day07; + +import java.util.List; + +public class SelectedSteps { + + private char leastStep; + private char nextStepToCheck; + private char stepWhenInstructionIsEmpty; + private char stepWhenInstructionIsDuplicated; + private List startingSteps; + + + public SelectedSteps() { + this.leastStep = Character.MIN_VALUE; + this.nextStepToCheck = Character.MIN_VALUE; + this.stepWhenInstructionIsEmpty = Character.MIN_VALUE; + this.stepWhenInstructionIsDuplicated = Character.MIN_VALUE; + } + + public char getLeastStep() { + return leastStep; + } + + public void setLeastStep(final char leastStep) { + this.leastStep = leastStep; + } + + public char getNextStepToCheck() { + return nextStepToCheck; + } + + public void setNextStepToCheck(final char nextStepToCheck) { + this.nextStepToCheck = nextStepToCheck; + } + + public char getStepWhenInstructionIsEmpty() { + return stepWhenInstructionIsEmpty; + } + + public void setStepWhenInstructionIsEmpty(final char stepWhenInstructionIsEmpty) { + this.stepWhenInstructionIsEmpty = stepWhenInstructionIsEmpty; + } + + public char getStepWhenInstructionIsDuplicated() { + return stepWhenInstructionIsDuplicated; + } + + public void setStepWhenInstructionIsDuplicated(final char stepWhenInstructionIsDuplicated) { + this.stepWhenInstructionIsDuplicated = stepWhenInstructionIsDuplicated; + } + + public List getStartingSteps() { + return startingSteps; + } + + public void setStartingSteps(final List startingSteps) { + this.startingSteps = startingSteps; + } + + public char getStartingStep() { + return startingSteps.get(0); + } +} diff --git a/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java b/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java index 1420676..158606b 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java @@ -9,26 +9,18 @@ public class StepSorter { @Nonnull private final List stepInstructions; - private List startingSteps; @Nonnull private List availableStepInstructions = new ArrayList<>(); @Nonnull private List availableStepInstructionsNotUsed = new ArrayList<>(); - private StepInstruction nextStepInstruction; - private char stepWhenInstructionIsEmpty; - - private char stepWhenInstructionIsDuplicated; - - private char leastStep; - - private char nextStepToCheck; - private final SortedSteps sortedSteps; + private final SelectedSteps selectedSteps; public StepSorter(@Nonnull final List stepInstructions) { this.stepInstructions = requireNonNull(stepInstructions, "stepInstructions"); this.sortedSteps = new SortedSteps(); + this.selectedSteps = new SelectedSteps(); } @@ -36,7 +28,7 @@ public String getSortedSteps() { initialiseStarting(); for (int i = 0; i < stepInstructions.size(); i++) { - setAvailableStepInstructions(nextStepToCheck); + setAvailableStepInstructions(selectedSteps.getNextStepToCheck()); getNextStepInstructionByAlphabeticalOrder(); @@ -48,41 +40,11 @@ public String getSortedSteps() { return sortedSteps.getSequenceAsString(); } - public List getStartingSteps() { - return startingSteps; - } - - private char getStartingStep() { - return startingSteps.get(0); - } - - private void setNextStepToCheck() { - if (nextStepInstruction != null) { - this.nextStepToCheck = nextStepInstruction.finishedBefore(); - if (nextStepToCheck == leastStep) { - setNextStepWhenDuplicate(); - this.nextStepToCheck = stepWhenInstructionIsDuplicated; - } - } else { - setNextStepWhenEmpty(); - this.nextStepToCheck = stepWhenInstructionIsEmpty; - } - } - - private void addStepToResult() { - sortedSteps.addStep(nextStepToCheck); - setLeastStep(); - } - - private void setLeastStep() { - this.leastStep = nextStepToCheck; - } - private void initialiseStarting() { findStartingStep(); setAvailableStarterOptions(); - this.sortedSteps.addStep(getStartingStep()); - this.nextStepToCheck = getStartingStep(); + this.sortedSteps.addStep(selectedSteps.getStartingStep()); + this.selectedSteps.setNextStepToCheck(selectedSteps.getStartingStep()); } public void findStartingStep() { @@ -96,16 +58,17 @@ public void findStartingStep() { stepsWithoutPreCondition.removeAll(stepsFinishedBefore); final Set stepsWithoutPreConditionDuplicateFree = new HashSet<>(stepsWithoutPreCondition); - - this.startingSteps = new ArrayList<>(stepsWithoutPreConditionDuplicateFree); + this.selectedSteps.setStartingSteps(new ArrayList<>(stepsWithoutPreConditionDuplicateFree)); } + public void setAvailableStarterOptions() { - for (final char stepToCompare : startingSteps) { + for (final char stepToCompare : selectedSteps.getStartingSteps()) { availableStepInstructionsNotUsed.addAll(getAvailableStepInstructions(stepToCompare)); } } + private void setAvailableStepInstructions(final char stepToCompare) { final Set availableInstructions = new HashSet<>(); @@ -133,12 +96,47 @@ private void getNextStepInstructionByAlphabeticalOrder() { } } + private void sortInstructionsAlphabeticalByFinishedBefore() { + this.availableStepInstructions = availableStepInstructions + .stream() + .sorted(Comparator.comparing(StepInstruction::finishedBefore)) + .toList(); + } + private boolean isNextStepInstruction(final int i) { final StepInstruction possibleNextInstruction = availableStepInstructions.get(i); return isPrerequisiteComplete(possibleNextInstruction); } + private boolean isPrerequisiteComplete(@Nonnull final StepInstruction instructionToCheck) { + final char stepToCheck = instructionToCheck.finishedBefore(); + + if (stepIsAlreadyUsed(stepToCheck)) { + return false; + } + final List stepsNeededToBeCompleted = getStepsNeedToBeCompleted(stepToCheck); + + return isEveryNeededStepCompleted(stepsNeededToBeCompleted); + } + + private boolean stepIsAlreadyUsed(final char stepToCheck) { + return sortedSteps.getStepSequence().contains(stepToCheck); + } + + @Nonnull + private List getStepsNeedToBeCompleted(final char stepToCheck) { + return List.copyOf(stepInstructions) + .stream() + .filter(stepInstruction -> stepToCheck == stepInstruction.finishedBefore()) + .map(StepInstruction::step) + .toList(); + } + + private boolean isEveryNeededStepCompleted(@Nonnull final List stepsNeededToBeCompleted) { + return new HashSet<>(sortedSteps.getStepSequence()).containsAll(stepsNeededToBeCompleted); + } + private void setNextStepInstruction(final int i) { this.nextStepInstruction = availableStepInstructions.get(i); } @@ -149,20 +147,32 @@ private void setUnusedStepInstructions(final int i) { this.availableStepInstructionsNotUsed = stepInstructionsNotUsed; } - - private void setNextStepWhenEmpty() { - this.stepWhenInstructionIsEmpty = getAvailableStarterSteps().get(0); + private void setNextStepToCheck() { + if (nextStepInstruction != null) { + selectedSteps.setNextStepToCheck(nextStepInstruction.finishedBefore()); + if (selectedSteps.getNextStepToCheck() == selectedSteps.getLeastStep()) { + setNextStepWhenDuplicate(); + selectedSteps.setNextStepToCheck(selectedSteps.getStepWhenInstructionIsDuplicated()); + } + } else { + setNextStepWhenEmpty(); + selectedSteps.setNextStepToCheck(selectedSteps.getStepWhenInstructionIsEmpty()); + } } private void setNextStepWhenDuplicate() { if (!getAvailableStarterSteps().isEmpty()) { - this.stepWhenInstructionIsDuplicated = getAvailableStarterSteps().get(0); + selectedSteps.setStepWhenInstructionIsDuplicated(getAvailableStarterSteps().get(0)); } } + private void setNextStepWhenEmpty() { + selectedSteps.setStepWhenInstructionIsEmpty(getAvailableStarterSteps().get(0)); + } + @Nonnull private List getAvailableStarterSteps() { - final List starterSteps = new ArrayList<>(startingSteps); + final List starterSteps = new ArrayList<>(selectedSteps.getStartingSteps()); final List actualSteps = new ArrayList<>(sortedSteps.getStepSequence()); starterSteps.removeAll(actualSteps); @@ -170,38 +180,12 @@ private List getAvailableStarterSteps() { return starterSteps; } - private void sortInstructionsAlphabeticalByFinishedBefore() { - this.availableStepInstructions = availableStepInstructions - .stream() - .sorted(Comparator.comparing(StepInstruction::finishedBefore)) - .toList(); - } - - private boolean isPrerequisiteComplete(@Nonnull final StepInstruction instructionToCheck) { - final char stepToCheck = instructionToCheck.finishedBefore(); - - if (stepIsAlreadyUsed(stepToCheck)) { - return false; - } - final List stepsNeededToBeCompleted = getStepsNeedToBeCompleted(stepToCheck); - - return isEveryNeededStepCompleted(stepsNeededToBeCompleted); - } - - private boolean stepIsAlreadyUsed(final char stepToCheck) { - return sortedSteps.getStepSequence().contains(stepToCheck); - } - - @Nonnull - private List getStepsNeedToBeCompleted(final char stepToCheck) { - return List.copyOf(stepInstructions) - .stream() - .filter(stepInstruction -> stepToCheck == stepInstruction.finishedBefore()) - .map(StepInstruction::step) - .toList(); + private void addStepToResult() { + sortedSteps.addStep(selectedSteps.getNextStepToCheck()); + setLeastStep(); } - private boolean isEveryNeededStepCompleted(@Nonnull final List stepsNeededToBeCompleted) { - return new HashSet<>(sortedSteps.getStepSequence()).containsAll(stepsNeededToBeCompleted); + private void setLeastStep() { + selectedSteps.setLeastStep(selectedSteps.getNextStepToCheck()); } } From fac4bf98568eb3c68673200286e106e9b5f48f8c Mon Sep 17 00:00:00 2001 From: PascalWo Date: Tue, 23 Aug 2022 16:23:39 +0200 Subject: [PATCH 09/19] refactored to get helper classes --- .../days/day07/SelectedInstructions.java | 119 +++++++++ .../days/day07/SelectedSteps.java | 15 -- .../adventofcode/days/day07/SortedSteps.java | 7 + .../adventofcode/days/day07/Starter.java | 40 +++ .../adventofcode/days/day07/StepSorter.java | 230 ++++++++---------- .../adventofcode/days/day07/Day07Test.java | 120 ++++++++- .../days/day07/StepSorterTest.java | 31 ++- 7 files changed, 401 insertions(+), 161 deletions(-) create mode 100644 src/main/java/org/haffson/adventofcode/days/day07/SelectedInstructions.java create mode 100644 src/main/java/org/haffson/adventofcode/days/day07/Starter.java diff --git a/src/main/java/org/haffson/adventofcode/days/day07/SelectedInstructions.java b/src/main/java/org/haffson/adventofcode/days/day07/SelectedInstructions.java new file mode 100644 index 0000000..2af6d0f --- /dev/null +++ b/src/main/java/org/haffson/adventofcode/days/day07/SelectedInstructions.java @@ -0,0 +1,119 @@ +package org.haffson.adventofcode.days.day07; + +import javax.annotation.Nonnull; +import java.util.*; + +import static java.util.Objects.requireNonNull; + +public class SelectedInstructions { + + @Nonnull + private final List stepInstructions; + @Nonnull + private List availableStepInstructions = new ArrayList<>(); + @Nonnull + private List availableStepInstructionsNotUsed = new ArrayList<>(); + private StepInstruction nextStepInstruction; + + public StepInstruction getNextStepInstruction() { + return nextStepInstruction; + } + + public SelectedInstructions(@Nonnull final List stepInstructions) { + this.stepInstructions = requireNonNull(stepInstructions); + } + + public int getAmountOfInstructions() { + return stepInstructions.size(); + } + + public void setAvailableStarterOptions(@Nonnull final Starter starter) { + for (final char stepToCompare : starter.getStartingSteps()) { + + availableStepInstructionsNotUsed.addAll(getAvailableStepInstructions(stepToCompare)); + } + } + + @Nonnull + private List getAvailableStepInstructions(final char stepToCompare) { + return List.copyOf(stepInstructions).stream() + .filter(stepInstruction -> stepToCompare == stepInstruction.step()). + toList(); + } + + public void setAvailableStepInstructions(final char stepToCompare) { + final Set availableInstructions = new HashSet<>(); + + availableInstructions.addAll(getAvailableStepInstructions(stepToCompare)); + availableInstructions.addAll(availableStepInstructionsNotUsed); + + this.availableStepInstructions = new ArrayList<>(availableInstructions); + } + + public int getAmountOfAvailableStepInstructions() { + return availableStepInstructions.size(); + } + + public void getNextStepInstructionByAlphabeticalOrder(@Nonnull final SortedSteps sortedSteps) { + sortInstructionsAlphabeticalByFinishedBefore(); + for (int i = 0; i < getAmountOfAvailableStepInstructions(); i++) { + if (isNextStepInstruction(i, sortedSteps)) { + setNextStepInstruction(i); + setUnusedStepInstructions(i); + break; + } + } + } + + private void sortInstructionsAlphabeticalByFinishedBefore() { + this.availableStepInstructions = availableStepInstructions + .stream() + .sorted(Comparator.comparing(StepInstruction::finishedBefore)) + .toList(); + } + + private boolean isNextStepInstruction(final int i, @Nonnull final SortedSteps sortedSteps) { + final StepInstruction possibleNextInstruction = availableStepInstructions.get(i); + + return isPrerequisiteComplete(possibleNextInstruction, sortedSteps); + } + + private boolean isPrerequisiteComplete(@Nonnull final StepInstruction instructionToCheck, @Nonnull final SortedSteps sortedSteps) { + final char stepToCheck = instructionToCheck.finishedBefore(); + + if (stepIsAlreadyUsed(stepToCheck, sortedSteps)) { + return false; + } + final List stepsNeededToBeCompleted = getStepsNeedToBeCompleted(stepToCheck); + + return isEveryNeededStepCompleted(stepsNeededToBeCompleted, sortedSteps); + } + + private boolean stepIsAlreadyUsed(final char stepToCheck, @Nonnull final SortedSteps sortedSteps) { + return sortedSteps.getStepSequence().contains(stepToCheck); + } + + @Nonnull + private List getStepsNeedToBeCompleted(final char stepToCheck) { + return List.copyOf(stepInstructions) + .stream() + .filter(stepInstruction -> stepToCheck == stepInstruction.finishedBefore()) + .map(StepInstruction::step) + .toList(); + } + + private boolean isEveryNeededStepCompleted(@Nonnull final List stepsNeededToBeCompleted, @Nonnull final SortedSteps sortedSteps) { + return new HashSet<>(sortedSteps.getStepSequence()).containsAll(stepsNeededToBeCompleted); + } + + private void setNextStepInstruction(final int i) { + this.nextStepInstruction = availableStepInstructions.get(i); + } + + private void setUnusedStepInstructions(final int i) { + final List stepInstructionsNotUsed = new ArrayList<>(availableStepInstructions); + stepInstructionsNotUsed.remove(i); + this.availableStepInstructionsNotUsed = stepInstructionsNotUsed; + } + +} diff --git a/src/main/java/org/haffson/adventofcode/days/day07/SelectedSteps.java b/src/main/java/org/haffson/adventofcode/days/day07/SelectedSteps.java index 9668108..12914c3 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/SelectedSteps.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/SelectedSteps.java @@ -1,14 +1,11 @@ package org.haffson.adventofcode.days.day07; -import java.util.List; - public class SelectedSteps { private char leastStep; private char nextStepToCheck; private char stepWhenInstructionIsEmpty; private char stepWhenInstructionIsDuplicated; - private List startingSteps; public SelectedSteps() { @@ -49,16 +46,4 @@ public char getStepWhenInstructionIsDuplicated() { public void setStepWhenInstructionIsDuplicated(final char stepWhenInstructionIsDuplicated) { this.stepWhenInstructionIsDuplicated = stepWhenInstructionIsDuplicated; } - - public List getStartingSteps() { - return startingSteps; - } - - public void setStartingSteps(final List startingSteps) { - this.startingSteps = startingSteps; - } - - public char getStartingStep() { - return startingSteps.get(0); - } } diff --git a/src/main/java/org/haffson/adventofcode/days/day07/SortedSteps.java b/src/main/java/org/haffson/adventofcode/days/day07/SortedSteps.java index c9b0645..d687bb8 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/SortedSteps.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/SortedSteps.java @@ -18,11 +18,18 @@ public List getStepSequence() { } public void addStep(final char nextStepToCheck) { + if (isStepToCheckEmpty(nextStepToCheck)) { + return; + } if (!stepSequence.contains(nextStepToCheck)) { this.stepSequence.add(nextStepToCheck); } } + private boolean isStepToCheckEmpty(final char stepToCheck) { + return stepToCheck == Character.MIN_VALUE; + } + @Nonnull public String getSequenceAsString() { return stepSequence.stream().map(String::valueOf).collect(Collectors.joining()); diff --git a/src/main/java/org/haffson/adventofcode/days/day07/Starter.java b/src/main/java/org/haffson/adventofcode/days/day07/Starter.java new file mode 100644 index 0000000..ef5bee2 --- /dev/null +++ b/src/main/java/org/haffson/adventofcode/days/day07/Starter.java @@ -0,0 +1,40 @@ +package org.haffson.adventofcode.days.day07; + +import javax.annotation.Nonnull; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import static java.util.Objects.requireNonNull; + +public class Starter { + List startingSteps; + private final List stepInstructions; + + public Starter(@Nonnull final List stepInstructions) { + this.stepInstructions = requireNonNull(stepInstructions, "stepInstructions"); + } + + public void setStartingSteps() { + final List steps = new ArrayList<>(); + this.stepInstructions.forEach(stepInstruction -> steps.add(stepInstruction.step())); + + final List stepsFinishedBefore = new ArrayList<>(); + this.stepInstructions.forEach(stepInstruction -> stepsFinishedBefore.add(stepInstruction.finishedBefore())); + + final List stepsWithoutPreCondition = new ArrayList<>(steps); + stepsWithoutPreCondition.removeAll(stepsFinishedBefore); + final Set stepsWithoutPreConditionDuplicateFree = new HashSet<>(stepsWithoutPreCondition); + + this.startingSteps = new ArrayList<>(stepsWithoutPreConditionDuplicateFree); + } + + public List getStartingSteps() { + return startingSteps; + } + + public char getStartingStep() { + return startingSteps.get(0); + } +} diff --git a/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java b/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java index 158606b..75a01ac 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java @@ -1,36 +1,37 @@ package org.haffson.adventofcode.days.day07; import javax.annotation.Nonnull; -import java.util.*; - -import static java.util.Objects.requireNonNull; +import java.util.ArrayList; +import java.util.List; public class StepSorter { - @Nonnull - private final List stepInstructions; - @Nonnull - private List availableStepInstructions = new ArrayList<>(); - @Nonnull - private List availableStepInstructionsNotUsed = new ArrayList<>(); - private StepInstruction nextStepInstruction; + // @Nonnull +// private final List stepInstructions; +// @Nonnull +// private List availableStepInstructions = new ArrayList<>(); +// @Nonnull +// private List availableStepInstructionsNotUsed = new ArrayList<>(); +// private StepInstruction nextStepInstruction; private final SortedSteps sortedSteps; private final SelectedSteps selectedSteps; + private final Starter starter; + private final SelectedInstructions selectedInstructions; public StepSorter(@Nonnull final List stepInstructions) { - this.stepInstructions = requireNonNull(stepInstructions, "stepInstructions"); + this.selectedInstructions = new SelectedInstructions(stepInstructions); this.sortedSteps = new SortedSteps(); this.selectedSteps = new SelectedSteps(); + this.starter = new Starter(stepInstructions); } - public String getSortedSteps() { initialiseStarting(); - for (int i = 0; i < stepInstructions.size(); i++) { - setAvailableStepInstructions(selectedSteps.getNextStepToCheck()); + for (int i = 0; i < selectedInstructions.getAmountOfInstructions(); i++) { + selectedInstructions.setAvailableStepInstructions(selectedSteps.getNextStepToCheck()); - getNextStepInstructionByAlphabeticalOrder(); + selectedInstructions.getNextStepInstructionByAlphabeticalOrder(sortedSteps); setNextStepToCheck(); @@ -41,115 +42,98 @@ public String getSortedSteps() { } private void initialiseStarting() { - findStartingStep(); - setAvailableStarterOptions(); - this.sortedSteps.addStep(selectedSteps.getStartingStep()); - this.selectedSteps.setNextStepToCheck(selectedSteps.getStartingStep()); - } - - public void findStartingStep() { - final List steps = new ArrayList<>(); - this.stepInstructions.forEach(stepInstruction -> steps.add(stepInstruction.step())); - - final List stepsFinishedBefore = new ArrayList<>(); - this.stepInstructions.forEach(stepInstruction -> stepsFinishedBefore.add(stepInstruction.finishedBefore())); - - final List stepsWithoutPreCondition = new ArrayList<>(steps); - stepsWithoutPreCondition.removeAll(stepsFinishedBefore); - final Set stepsWithoutPreConditionDuplicateFree = new HashSet<>(stepsWithoutPreCondition); - - this.selectedSteps.setStartingSteps(new ArrayList<>(stepsWithoutPreConditionDuplicateFree)); - } - - - public void setAvailableStarterOptions() { - for (final char stepToCompare : selectedSteps.getStartingSteps()) { - availableStepInstructionsNotUsed.addAll(getAvailableStepInstructions(stepToCompare)); - } - } - - - private void setAvailableStepInstructions(final char stepToCompare) { - final Set availableInstructions = new HashSet<>(); - - availableInstructions.addAll(getAvailableStepInstructions(stepToCompare)); - availableInstructions.addAll(availableStepInstructionsNotUsed); - - this.availableStepInstructions = new ArrayList<>(availableInstructions); - } - - @Nonnull - private List getAvailableStepInstructions(final char stepToCompare) { - return List.copyOf(stepInstructions).stream() - .filter(stepInstruction -> stepToCompare == stepInstruction.step()). - toList(); - } - - private void getNextStepInstructionByAlphabeticalOrder() { - sortInstructionsAlphabeticalByFinishedBefore(); - for (int i = 0; i < availableStepInstructions.size(); i++) { - if (isNextStepInstruction(i)) { - setNextStepInstruction(i); - setUnusedStepInstructions(i); - break; - } - } - } - - private void sortInstructionsAlphabeticalByFinishedBefore() { - this.availableStepInstructions = availableStepInstructions - .stream() - .sorted(Comparator.comparing(StepInstruction::finishedBefore)) - .toList(); - } - - private boolean isNextStepInstruction(final int i) { - final StepInstruction possibleNextInstruction = availableStepInstructions.get(i); - - return isPrerequisiteComplete(possibleNextInstruction); - } - - private boolean isPrerequisiteComplete(@Nonnull final StepInstruction instructionToCheck) { - final char stepToCheck = instructionToCheck.finishedBefore(); - - if (stepIsAlreadyUsed(stepToCheck)) { - return false; - } - final List stepsNeededToBeCompleted = getStepsNeedToBeCompleted(stepToCheck); - - return isEveryNeededStepCompleted(stepsNeededToBeCompleted); - } - - private boolean stepIsAlreadyUsed(final char stepToCheck) { - return sortedSteps.getStepSequence().contains(stepToCheck); - } - - @Nonnull - private List getStepsNeedToBeCompleted(final char stepToCheck) { - return List.copyOf(stepInstructions) - .stream() - .filter(stepInstruction -> stepToCheck == stepInstruction.finishedBefore()) - .map(StepInstruction::step) - .toList(); - } - - private boolean isEveryNeededStepCompleted(@Nonnull final List stepsNeededToBeCompleted) { - return new HashSet<>(sortedSteps.getStepSequence()).containsAll(stepsNeededToBeCompleted); - } - - private void setNextStepInstruction(final int i) { - this.nextStepInstruction = availableStepInstructions.get(i); - } - - private void setUnusedStepInstructions(final int i) { - final List stepInstructionsNotUsed = new ArrayList<>(availableStepInstructions); - stepInstructionsNotUsed.remove(i); - this.availableStepInstructionsNotUsed = stepInstructionsNotUsed; - } + starter.setStartingSteps(); + selectedInstructions.setAvailableStarterOptions(starter); + this.sortedSteps.addStep(starter.getStartingStep()); + this.selectedSteps.setNextStepToCheck(starter.getStartingStep()); + } +// public void setAvailableStarterOptions() { +// for (final char stepToCompare : startingSteps.getStartingSteps()) { +// selectedInstructions.availableStepInstructionsNotUsed.addAll(getAvailableStepInstructions(stepToCompare)); +// } +// } + +// private void setAvailableStepInstructions(final char stepToCompare) { +// final Set availableInstructions = new HashSet<>(); +// +// availableInstructions.addAll(getAvailableStepInstructions(stepToCompare)); +// availableInstructions.addAll(availableStepInstructionsNotUsed); +// +// this.availableStepInstructions = new ArrayList<>(availableInstructions); +// } + +// @Nonnull +// private List getAvailableStepInstructions(final char stepToCompare) { +// return List.copyOf(stepInstructions).stream() +// .filter(stepInstruction -> stepToCompare == stepInstruction.step()). +// toList(); +// } + +// private void getNextStepInstructionByAlphabeticalOrder() { +// selectedInstructions.sortInstructionsAlphabeticalByFinishedBefore(); +// for (int i = 0; i < selectedInstructions.getAmountOfAvailableStepInstructions(); i++) { +// if (isNextStepInstruction(i)) { +// setNextStepInstruction(i); +// setUnusedStepInstructions(i); +// break; +// } +// } +// } + +// private void sortInstructionsAlphabeticalByFinishedBefore() { +// this.availableStepInstructions = availableStepInstructions +// .stream() +// .sorted(Comparator.comparing(StepInstruction::finishedBefore)) +// .toList(); +// } + +// private boolean isNextStepInstruction(final int i) { +// final StepInstruction possibleNextInstruction = availableStepInstructions.get(i); +// +// return isPrerequisiteComplete(possibleNextInstruction); +// } + +// private boolean isPrerequisiteComplete(@Nonnull final StepInstruction instructionToCheck) { +// final char stepToCheck = instructionToCheck.finishedBefore(); +// +// if (stepIsAlreadyUsed(stepToCheck)) { +// return false; +// } +// final List stepsNeededToBeCompleted = getStepsNeedToBeCompleted(stepToCheck); +// +// return isEveryNeededStepCompleted(stepsNeededToBeCompleted); +// } + +// private boolean stepIsAlreadyUsed(final char stepToCheck) { +// return sortedSteps.getStepSequence().contains(stepToCheck); +// } + +// @Nonnull +// private List getStepsNeedToBeCompleted(final char stepToCheck) { +// return List.copyOf(stepInstructions) +// .stream() +// .filter(stepInstruction -> stepToCheck == stepInstruction.finishedBefore()) +// .map(StepInstruction::step) +// .toList(); +// } + +// private boolean isEveryNeededStepCompleted(@Nonnull final List stepsNeededToBeCompleted) { +// return new HashSet<>(sortedSteps.getStepSequence()).containsAll(stepsNeededToBeCompleted); +// } + +// private void setNextStepInstruction(final int i) { +// this.nextStepInstruction = availableStepInstructions.get(i); +// } +// +// private void setUnusedStepInstructions(final int i) { +// final List stepInstructionsNotUsed = new ArrayList<>(availableStepInstructions); +// stepInstructionsNotUsed.remove(i); +// this.availableStepInstructionsNotUsed = stepInstructionsNotUsed; +// } private void setNextStepToCheck() { - if (nextStepInstruction != null) { - selectedSteps.setNextStepToCheck(nextStepInstruction.finishedBefore()); + if (selectedInstructions.getNextStepInstruction() != null) { + selectedSteps.setNextStepToCheck(selectedInstructions.getNextStepInstruction().finishedBefore()); if (selectedSteps.getNextStepToCheck() == selectedSteps.getLeastStep()) { setNextStepWhenDuplicate(); selectedSteps.setNextStepToCheck(selectedSteps.getStepWhenInstructionIsDuplicated()); @@ -172,7 +156,7 @@ private void setNextStepWhenEmpty() { @Nonnull private List getAvailableStarterSteps() { - final List starterSteps = new ArrayList<>(selectedSteps.getStartingSteps()); + final List starterSteps = new ArrayList<>(starter.getStartingSteps()); final List actualSteps = new ArrayList<>(sortedSteps.getStepSequence()); starterSteps.removeAll(actualSteps); diff --git a/src/test/java/org/haffson/adventofcode/days/day07/Day07Test.java b/src/test/java/org/haffson/adventofcode/days/day07/Day07Test.java index 835a718..58d6af5 100644 --- a/src/test/java/org/haffson/adventofcode/days/day07/Day07Test.java +++ b/src/test/java/org/haffson/adventofcode/days/day07/Day07Test.java @@ -22,14 +22,119 @@ void setUp() { when(fileReaders.getInputList("src/main/resources/puzzle_input/day7_input.txt")) .thenReturn(List.of( - "Step C must be finished before step A can begin.", - "Step C must be finished before step F can begin.", + "Step P must be finished before step Z can begin.", + "Step E must be finished before step O can begin.", + "Step X must be finished before step T can begin.", + "Step W must be finished before step V can begin.", + "Step K must be finished before step Y can begin.", + "Step C must be finished before step M can begin.", + "Step S must be finished before step R can begin.", + "Step T must be finished before step H can begin.", + "Step Z must be finished before step V can begin.", + "Step F must be finished before step L can begin.", + "Step V must be finished before step A can begin.", + "Step I must be finished before step A can begin.", + "Step J must be finished before step M can begin.", + "Step N must be finished before step Y can begin.", "Step A must be finished before step B can begin.", - "Step A must be finished before step D can begin.", - "Step B must be finished before step E can begin.", - "Step D must be finished before step E can begin.", - "Step F must be finished before step E can begin." + "Step H must be finished before step Q can begin.", + "Step Q must be finished before step O can begin.", + "Step D must be finished before step O can begin.", + "Step Y must be finished before step O can begin.", + "Step G must be finished before step L can begin.", + "Step B must be finished before step M can begin.", + "Step L must be finished before step U can begin.", + "Step M must be finished before step O can begin.", + "Step O must be finished before step U can begin.", + "Step R must be finished before step U can begin.", + "Step M must be finished before step U can begin.", + "Step Q must be finished before step U can begin.", + "Step K must be finished before step U can begin.", + "Step D must be finished before step R can begin.", + "Step A must be finished before step M can begin.", + "Step A must be finished before step Q can begin.", + "Step V must be finished before step Y can begin.", + "Step H must be finished before step G can begin.", + "Step P must be finished before step K can begin.", + "Step N must be finished before step A can begin.", + "Step P must be finished before step H can begin.", + "Step X must be finished before step Z can begin.", + "Step X must be finished before step K can begin.", + "Step Y must be finished before step U can begin.", + "Step F must be finished before step Q can begin.", + "Step W must be finished before step M can begin.", + "Step B must be finished before step L can begin.", + "Step E must be finished before step L can begin.", + "Step N must be finished before step O can begin.", + "Step I must be finished before step G can begin.", + "Step J must be finished before step H can begin.", + "Step Z must be finished before step N can begin.", + "Step V must be finished before step N can begin.", + "Step F must be finished before step B can begin.", + "Step A must be finished before step Y can begin.", + "Step Q must be finished before step R can begin.", + "Step L must be finished before step O can begin.", + "Step H must be finished before step U can begin.", + "Step V must be finished before step G can begin.", + "Step Z must be finished before step B can begin.", + "Step V must be finished before step J can begin.", + "Step V must be finished before step O can begin.", + "Step T must be finished before step D can begin.", + "Step Y must be finished before step M can begin.", + "Step B must be finished before step R can begin.", + "Step O must be finished before step R can begin.", + "Step C must be finished before step V can begin.", + "Step W must be finished before step T can begin.", + "Step P must be finished before step N can begin.", + "Step L must be finished before step R can begin.", + "Step V must be finished before step U can begin.", + "Step C must be finished before step J can begin.", + "Step N must be finished before step R can begin.", + "Step X must be finished before step S can begin.", + "Step X must be finished before step A can begin.", + "Step G must be finished before step O can begin.", + "Step A must be finished before step O can begin.", + "Step X must be finished before step O can begin.", + "Step D must be finished before step Y can begin.", + "Step C must be finished before step G can begin.", + "Step K must be finished before step D can begin.", + "Step N must be finished before step B can begin.", + "Step C must be finished before step B can begin.", + "Step W must be finished before step F can begin.", + "Step E must be finished before step Z can begin.", + "Step S must be finished before step V can begin.", + "Step G must be finished before step M can begin.", + "Step T must be finished before step B can begin.", + "Step W must be finished before step C can begin.", + "Step D must be finished before step G can begin.", + "Step L must be finished before step M can begin.", + "Step H must be finished before step D can begin.", + "Step G must be finished before step R can begin.", + "Step T must be finished before step J can begin.", + "Step A must be finished before step R can begin.", + "Step B must be finished before step O can begin.", + "Step J must be finished before step R can begin.", + "Step G must be finished before step U can begin.", + "Step K must be finished before step O can begin.", + "Step V must be finished before step L can begin.", + "Step M must be finished before step R can begin.", + "Step D must be finished before step U can begin.", + "Step H must be finished before step Y can begin.", + "Step P must be finished before step W can begin.", + "Step K must be finished before step I can begin.", + "Step J must be finished before step G can begin." )); + +// when(fileReaders.getInputList("src/main/resources/puzzle_input/day7_input.txt")) +// .thenReturn(List.of( +// "Step C must be finished before step A can begin.", +// "Step C must be finished before step F can begin.", +// "Step A must be finished before step B can begin.", +// "Step A must be finished before step D can begin.", +// "Step B must be finished before step E can begin.", +// "Step D must be finished before step E can begin.", +// "Step F must be finished before step E can begin." +// )); } @DisplayName("get the current AoC Day") @@ -44,7 +149,8 @@ void testGetDay() { @Test void test_firstPart_returnsExpectedResult() { //arrange - final String expectedResult = "Part 1 - : " + "CABDFE"; +// final String expectedResult = "Part 1 - : " + "CABDFE"; + final String expectedResult = "Part 1 - : " + "EPWCFXKISTZVJHDGNABLQYMORU"; //act final String actualResult = day07.firstPart(); diff --git a/src/test/java/org/haffson/adventofcode/days/day07/StepSorterTest.java b/src/test/java/org/haffson/adventofcode/days/day07/StepSorterTest.java index ef3af3c..2ac7579 100644 --- a/src/test/java/org/haffson/adventofcode/days/day07/StepSorterTest.java +++ b/src/test/java/org/haffson/adventofcode/days/day07/StepSorterTest.java @@ -1,7 +1,6 @@ package org.haffson.adventofcode.days.day07; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.List; @@ -15,21 +14,21 @@ void setUp() { } - @DisplayName("find starting step character") - @Test - void findStartingStep_shouldReturnStartingStep() { - //arrange - final List stepInstructions = List.of(new StepInstruction('C', 'A'), - new StepInstruction('C', 'F'), - new StepInstruction('A', 'B')); - final StepSorter stepSorter = new StepSorter(stepInstructions); - final List expectedResult = List.of('C'); - //act - stepSorter.findStartingStep(); - final List actualResult = stepSorter.getStartingSteps(); - //assert - assertThat(actualResult).isEqualTo(expectedResult); - } +// @DisplayName("find starting step character") +// @Test +// void findStartingStep_shouldReturnStartingStep() { +// //arrange +// final List stepInstructions = List.of(new StepInstruction('C', 'A'), +// new StepInstruction('C', 'F'), +// new StepInstruction('A', 'B')); +// final StepSorter stepSorter = new StepSorter(stepInstructions); +// final List expectedResult = List.of('C'); +// //act +// stepSorter.findStartingStep(); +// final List actualResult = stepSorter.getStartingSteps(); +// //assert +// assertThat(actualResult).isEqualTo(expectedResult); +// } @Test void getSortedSteps_shouldReturnSortedStepsAsString() { From 8024c6153699ed21259f3fbd2d4b30c3d2990d70 Mon Sep 17 00:00:00 2001 From: PascalWo Date: Tue, 23 Aug 2022 16:25:42 +0200 Subject: [PATCH 10/19] deleted comments --- .../adventofcode/days/day07/StepSorter.java | 91 ------------------- 1 file changed, 91 deletions(-) diff --git a/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java b/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java index 75a01ac..da815c9 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java @@ -5,14 +5,6 @@ import java.util.List; public class StepSorter { - - // @Nonnull -// private final List stepInstructions; -// @Nonnull -// private List availableStepInstructions = new ArrayList<>(); -// @Nonnull -// private List availableStepInstructionsNotUsed = new ArrayList<>(); -// private StepInstruction nextStepInstruction; private final SortedSteps sortedSteps; private final SelectedSteps selectedSteps; private final Starter starter; @@ -47,89 +39,6 @@ private void initialiseStarting() { this.sortedSteps.addStep(starter.getStartingStep()); this.selectedSteps.setNextStepToCheck(starter.getStartingStep()); } -// public void setAvailableStarterOptions() { -// for (final char stepToCompare : startingSteps.getStartingSteps()) { -// selectedInstructions.availableStepInstructionsNotUsed.addAll(getAvailableStepInstructions(stepToCompare)); -// } -// } - -// private void setAvailableStepInstructions(final char stepToCompare) { -// final Set availableInstructions = new HashSet<>(); -// -// availableInstructions.addAll(getAvailableStepInstructions(stepToCompare)); -// availableInstructions.addAll(availableStepInstructionsNotUsed); -// -// this.availableStepInstructions = new ArrayList<>(availableInstructions); -// } - -// @Nonnull -// private List getAvailableStepInstructions(final char stepToCompare) { -// return List.copyOf(stepInstructions).stream() -// .filter(stepInstruction -> stepToCompare == stepInstruction.step()). -// toList(); -// } - -// private void getNextStepInstructionByAlphabeticalOrder() { -// selectedInstructions.sortInstructionsAlphabeticalByFinishedBefore(); -// for (int i = 0; i < selectedInstructions.getAmountOfAvailableStepInstructions(); i++) { -// if (isNextStepInstruction(i)) { -// setNextStepInstruction(i); -// setUnusedStepInstructions(i); -// break; -// } -// } -// } - -// private void sortInstructionsAlphabeticalByFinishedBefore() { -// this.availableStepInstructions = availableStepInstructions -// .stream() -// .sorted(Comparator.comparing(StepInstruction::finishedBefore)) -// .toList(); -// } - -// private boolean isNextStepInstruction(final int i) { -// final StepInstruction possibleNextInstruction = availableStepInstructions.get(i); -// -// return isPrerequisiteComplete(possibleNextInstruction); -// } - -// private boolean isPrerequisiteComplete(@Nonnull final StepInstruction instructionToCheck) { -// final char stepToCheck = instructionToCheck.finishedBefore(); -// -// if (stepIsAlreadyUsed(stepToCheck)) { -// return false; -// } -// final List stepsNeededToBeCompleted = getStepsNeedToBeCompleted(stepToCheck); -// -// return isEveryNeededStepCompleted(stepsNeededToBeCompleted); -// } - -// private boolean stepIsAlreadyUsed(final char stepToCheck) { -// return sortedSteps.getStepSequence().contains(stepToCheck); -// } - -// @Nonnull -// private List getStepsNeedToBeCompleted(final char stepToCheck) { -// return List.copyOf(stepInstructions) -// .stream() -// .filter(stepInstruction -> stepToCheck == stepInstruction.finishedBefore()) -// .map(StepInstruction::step) -// .toList(); -// } - -// private boolean isEveryNeededStepCompleted(@Nonnull final List stepsNeededToBeCompleted) { -// return new HashSet<>(sortedSteps.getStepSequence()).containsAll(stepsNeededToBeCompleted); -// } - -// private void setNextStepInstruction(final int i) { -// this.nextStepInstruction = availableStepInstructions.get(i); -// } -// -// private void setUnusedStepInstructions(final int i) { -// final List stepInstructionsNotUsed = new ArrayList<>(availableStepInstructions); -// stepInstructionsNotUsed.remove(i); -// this.availableStepInstructionsNotUsed = stepInstructionsNotUsed; -// } private void setNextStepToCheck() { if (selectedInstructions.getNextStepInstruction() != null) { From 15d0d3093292ccbcec60632ab7b0a6e3423d519c Mon Sep 17 00:00:00 2001 From: PascalWo Date: Tue, 23 Aug 2022 17:32:54 +0200 Subject: [PATCH 11/19] Refactored constructor parameters for SelectedInstructions.java --- .../days/day07/SelectedInstructions.java | 34 ++++++++----------- .../adventofcode/days/day07/SortedSteps.java | 9 +++++ .../adventofcode/days/day07/StepSorter.java | 4 +-- 3 files changed, 25 insertions(+), 22 deletions(-) diff --git a/src/main/java/org/haffson/adventofcode/days/day07/SelectedInstructions.java b/src/main/java/org/haffson/adventofcode/days/day07/SelectedInstructions.java index 2af6d0f..d497612 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/SelectedInstructions.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/SelectedInstructions.java @@ -14,13 +14,16 @@ public class SelectedInstructions { @Nonnull private List availableStepInstructionsNotUsed = new ArrayList<>(); private StepInstruction nextStepInstruction; + @Nonnull + private final SortedSteps sortedSteps; - public StepInstruction getNextStepInstruction() { - return nextStepInstruction; + public SelectedInstructions(@Nonnull final List stepInstructions, @Nonnull final SortedSteps sortedSteps) { + this.stepInstructions = requireNonNull(stepInstructions, "stepInstructions"); + this.sortedSteps = requireNonNull(sortedSteps, "sortedSteps"); } - public SelectedInstructions(@Nonnull final List stepInstructions) { - this.stepInstructions = requireNonNull(stepInstructions); + public StepInstruction getNextStepInstruction() { + return nextStepInstruction; } public int getAmountOfInstructions() { @@ -54,10 +57,10 @@ public int getAmountOfAvailableStepInstructions() { return availableStepInstructions.size(); } - public void getNextStepInstructionByAlphabeticalOrder(@Nonnull final SortedSteps sortedSteps) { + public void getNextStepInstructionByAlphabeticalOrder() { sortInstructionsAlphabeticalByFinishedBefore(); for (int i = 0; i < getAmountOfAvailableStepInstructions(); i++) { - if (isNextStepInstruction(i, sortedSteps)) { + if (isNextStepInstruction(i)) { setNextStepInstruction(i); setUnusedStepInstructions(i); break; @@ -72,25 +75,21 @@ private void sortInstructionsAlphabeticalByFinishedBefore() { .toList(); } - private boolean isNextStepInstruction(final int i, @Nonnull final SortedSteps sortedSteps) { + private boolean isNextStepInstruction(final int i) { final StepInstruction possibleNextInstruction = availableStepInstructions.get(i); - return isPrerequisiteComplete(possibleNextInstruction, sortedSteps); + return isPrerequisiteComplete(possibleNextInstruction); } - private boolean isPrerequisiteComplete(@Nonnull final StepInstruction instructionToCheck, @Nonnull final SortedSteps sortedSteps) { + private boolean isPrerequisiteComplete(@Nonnull final StepInstruction instructionToCheck) { final char stepToCheck = instructionToCheck.finishedBefore(); - if (stepIsAlreadyUsed(stepToCheck, sortedSteps)) { + if (sortedSteps.stepIsAlreadyUsed(stepToCheck)) { return false; } final List stepsNeededToBeCompleted = getStepsNeedToBeCompleted(stepToCheck); - return isEveryNeededStepCompleted(stepsNeededToBeCompleted, sortedSteps); - } - - private boolean stepIsAlreadyUsed(final char stepToCheck, @Nonnull final SortedSteps sortedSteps) { - return sortedSteps.getStepSequence().contains(stepToCheck); + return sortedSteps.isEveryNeededStepCompleted(stepsNeededToBeCompleted); } @Nonnull @@ -102,10 +101,6 @@ private List getStepsNeedToBeCompleted(final char stepToCheck) { .toList(); } - private boolean isEveryNeededStepCompleted(@Nonnull final List stepsNeededToBeCompleted, @Nonnull final SortedSteps sortedSteps) { - return new HashSet<>(sortedSteps.getStepSequence()).containsAll(stepsNeededToBeCompleted); - } - private void setNextStepInstruction(final int i) { this.nextStepInstruction = availableStepInstructions.get(i); } @@ -115,5 +110,4 @@ private void setUnusedStepInstructions(final int i) { stepInstructionsNotUsed.remove(i); this.availableStepInstructionsNotUsed = stepInstructionsNotUsed; } - } diff --git a/src/main/java/org/haffson/adventofcode/days/day07/SortedSteps.java b/src/main/java/org/haffson/adventofcode/days/day07/SortedSteps.java index d687bb8..f6dd8b9 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/SortedSteps.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/SortedSteps.java @@ -3,6 +3,7 @@ import javax.annotation.Nonnull; import java.util.ArrayList; import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.stream.Collectors; @@ -34,4 +35,12 @@ private boolean isStepToCheckEmpty(final char stepToCheck) { public String getSequenceAsString() { return stepSequence.stream().map(String::valueOf).collect(Collectors.joining()); } + + public boolean stepIsAlreadyUsed(final char stepToCheck) { + return getStepSequence().contains(stepToCheck); + } + + public boolean isEveryNeededStepCompleted(@Nonnull final List stepsNeededToBeCompleted) { + return new HashSet<>(getStepSequence()).containsAll(stepsNeededToBeCompleted); + } } diff --git a/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java b/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java index da815c9..317e8af 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java @@ -11,8 +11,8 @@ public class StepSorter { private final SelectedInstructions selectedInstructions; public StepSorter(@Nonnull final List stepInstructions) { - this.selectedInstructions = new SelectedInstructions(stepInstructions); this.sortedSteps = new SortedSteps(); + this.selectedInstructions = new SelectedInstructions(stepInstructions, sortedSteps); this.selectedSteps = new SelectedSteps(); this.starter = new Starter(stepInstructions); } @@ -23,7 +23,7 @@ public String getSortedSteps() { for (int i = 0; i < selectedInstructions.getAmountOfInstructions(); i++) { selectedInstructions.setAvailableStepInstructions(selectedSteps.getNextStepToCheck()); - selectedInstructions.getNextStepInstructionByAlphabeticalOrder(sortedSteps); + selectedInstructions.getNextStepInstructionByAlphabeticalOrder(); setNextStepToCheck(); From 926fdf61a53890818371acae5cf3830e7c79318a Mon Sep 17 00:00:00 2001 From: PascalWo Date: Wed, 24 Aug 2022 14:55:51 +0200 Subject: [PATCH 12/19] More refactoring --- .../adventofcode/days/day07/Day07.java | 1 - .../days/day07/SelectedInstructions.java | 25 +++++++++- .../days/day07/SelectedSteps.java | 9 ++-- .../adventofcode/days/day07/StepSorter.java | 48 +++++++++++++------ 4 files changed, 61 insertions(+), 22 deletions(-) diff --git a/src/main/java/org/haffson/adventofcode/days/day07/Day07.java b/src/main/java/org/haffson/adventofcode/days/day07/Day07.java index bfa1e09..5e2429a 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/Day07.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/Day07.java @@ -77,7 +77,6 @@ private String calculateFirstPart(@Nonnull final List inputStringList) { return stepSorter.getSortedSteps(); } - private long calculateSecondPart(@Nonnull final List inputStringList) { return 0; } diff --git a/src/main/java/org/haffson/adventofcode/days/day07/SelectedInstructions.java b/src/main/java/org/haffson/adventofcode/days/day07/SelectedInstructions.java index d497612..c2d4f09 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/SelectedInstructions.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/SelectedInstructions.java @@ -22,6 +22,11 @@ public SelectedInstructions(@Nonnull final List stepInstruction this.sortedSteps = requireNonNull(sortedSteps, "sortedSteps"); } + @Nonnull + public List getStepInstructions() { + return stepInstructions; + } + public StepInstruction getNextStepInstruction() { return nextStepInstruction; } @@ -52,12 +57,20 @@ public void setAvailableStepInstructions(final char stepToCompare) { this.availableStepInstructions = new ArrayList<>(availableInstructions); } +//public List setAvailableStepInstructions(final char stepToCompare) { +// final Set availableInstructions = new HashSet<>(); +// +// availableInstructions.addAll(getAvailableStepInstructions(stepToCompare)); +// availableInstructions.addAll(availableStepInstructionsNotUsed); +// +// return new ArrayList<>(availableInstructions); +//} public int getAmountOfAvailableStepInstructions() { return availableStepInstructions.size(); } - public void getNextStepInstructionByAlphabeticalOrder() { + public void setNextStepInstructionByAlphabeticalOrder() { sortInstructionsAlphabeticalByFinishedBefore(); for (int i = 0; i < getAmountOfAvailableStepInstructions(); i++) { if (isNextStepInstruction(i)) { @@ -67,6 +80,16 @@ public void getNextStepInstructionByAlphabeticalOrder() { } } } +//public void setNextStepInstructionByAlphabeticalOrder() { +// sortInstructionsAlphabeticalByFinishedBefore(); +// for (int i = 0; i < getAmountOfAvailableStepInstructions(); i++) { +// if (isNextStepInstruction(i)) { +// setNextStepInstruction(i); +// setUnusedStepInstructions(i); +// break; +// } +// } +//} private void sortInstructionsAlphabeticalByFinishedBefore() { this.availableStepInstructions = availableStepInstructions diff --git a/src/main/java/org/haffson/adventofcode/days/day07/SelectedSteps.java b/src/main/java/org/haffson/adventofcode/days/day07/SelectedSteps.java index 12914c3..881656a 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/SelectedSteps.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/SelectedSteps.java @@ -7,7 +7,6 @@ public class SelectedSteps { private char stepWhenInstructionIsEmpty; private char stepWhenInstructionIsDuplicated; - public SelectedSteps() { this.leastStep = Character.MIN_VALUE; this.nextStepToCheck = Character.MIN_VALUE; @@ -19,10 +18,6 @@ public char getLeastStep() { return leastStep; } - public void setLeastStep(final char leastStep) { - this.leastStep = leastStep; - } - public char getNextStepToCheck() { return nextStepToCheck; } @@ -46,4 +41,8 @@ public char getStepWhenInstructionIsDuplicated() { public void setStepWhenInstructionIsDuplicated(final char stepWhenInstructionIsDuplicated) { this.stepWhenInstructionIsDuplicated = stepWhenInstructionIsDuplicated; } + + void setLeastStep() { + this.leastStep = this.getNextStepToCheck(); + } } diff --git a/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java b/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java index 317e8af..297a285 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java @@ -20,28 +20,46 @@ public StepSorter(@Nonnull final List stepInstructions) { public String getSortedSteps() { initialiseStarting(); - for (int i = 0; i < selectedInstructions.getAmountOfInstructions(); i++) { - selectedInstructions.setAvailableStepInstructions(selectedSteps.getNextStepToCheck()); +// for (int i = 0; i < selectedInstructions.getAmountOfInstructions(); i++) { + selectedInstructions.getStepInstructions().forEach(stepInstruction -> { + addNextStepToResult(); - selectedInstructions.getNextStepInstructionByAlphabeticalOrder(); +// setAvailableStepInstructions(); +// selectedInstructions.setNextStepInstructionByAlphabeticalOrder(); +// setNextStepToCheck(); +// addStepToResult(); + }); - setNextStepToCheck(); + return sortedSteps.getSequenceAsString(); + } - addStepToResult(); - } + private void addNextStepToResult() { +// final List availableStepInstructions = getAvailableStepInstructions(); + setAvailableStepInstructions(); - return sortedSteps.getSequenceAsString(); + selectedInstructions.setNextStepInstructionByAlphabeticalOrder(); + + setNextStepToCheck(); + + addStepToResult(); } + private void setAvailableStepInstructions(){ + selectedInstructions.setAvailableStepInstructions(selectedSteps.getNextStepToCheck()); + } + +// private List getAvailableStepInstructions(){ +// return selectedInstructions.setAvailableStepInstructions(selectedSteps.getNextStepToCheck()); +// } private void initialiseStarting() { starter.setStartingSteps(); selectedInstructions.setAvailableStarterOptions(starter); - this.sortedSteps.addStep(starter.getStartingStep()); - this.selectedSteps.setNextStepToCheck(starter.getStartingStep()); + sortedSteps.addStep(starter.getStartingStep()); + selectedSteps.setNextStepToCheck(starter.getStartingStep()); } private void setNextStepToCheck() { - if (selectedInstructions.getNextStepInstruction() != null) { + if (isNextStepInstructionEmpty()) { selectedSteps.setNextStepToCheck(selectedInstructions.getNextStepInstruction().finishedBefore()); if (selectedSteps.getNextStepToCheck() == selectedSteps.getLeastStep()) { setNextStepWhenDuplicate(); @@ -53,6 +71,10 @@ private void setNextStepToCheck() { } } + private boolean isNextStepInstructionEmpty(){ + return selectedInstructions.getNextStepInstruction() != null; + } + private void setNextStepWhenDuplicate() { if (!getAvailableStarterSteps().isEmpty()) { selectedSteps.setStepWhenInstructionIsDuplicated(getAvailableStarterSteps().get(0)); @@ -75,10 +97,6 @@ private List getAvailableStarterSteps() { private void addStepToResult() { sortedSteps.addStep(selectedSteps.getNextStepToCheck()); - setLeastStep(); - } - - private void setLeastStep() { - selectedSteps.setLeastStep(selectedSteps.getNextStepToCheck()); + selectedSteps.setLeastStep(); } } From e338706f363c888c83c4a104b904a42485884919 Mon Sep 17 00:00:00 2001 From: PascalWo Date: Tue, 30 Aug 2022 08:43:15 +0200 Subject: [PATCH 13/19] converts puzzle input to StepInformation --- .../adventofcode/days/day07/Day07.java | 85 +++++++++++++++++++ .../days/day07/SelectedInstructions.java | 12 ++- .../days/day07/StepInformation.java | 81 ++++++++++++++++++ .../adventofcode/days/day07/StepSorter.java | 7 +- .../adventofcode/days/day07/Day07Test.java | 78 +++++++++++++++++ 5 files changed, 255 insertions(+), 8 deletions(-) create mode 100644 src/main/java/org/haffson/adventofcode/days/day07/StepInformation.java diff --git a/src/main/java/org/haffson/adventofcode/days/day07/Day07.java b/src/main/java/org/haffson/adventofcode/days/day07/Day07.java index 5e2429a..6cffb3e 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/Day07.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/Day07.java @@ -7,8 +7,11 @@ import org.springframework.stereotype.Component; import javax.annotation.Nonnull; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; import static java.util.Objects.requireNonNull; @@ -80,4 +83,86 @@ private String calculateFirstPart(@Nonnull final List inputStringList) { private long calculateSecondPart(@Nonnull final List inputStringList) { return 0; } + + List getInstructions(@Nonnull final List inputStringList) { + return StepInstruction.of(inputStringList); + + } + + List convertInstructionsToSteps(@Nonnull final List stepInstructions) { + return getSteps(stepInstructions); + } + + @Nonnull + public List getSteps(@Nonnull final List stepInstructions) { + requireNonNull(stepInstructions, "stepInstructions"); + + final List combinedStepInformations = new ArrayList<>(); + + stepInstructions.forEach(stepInstruction -> { + final StepInformation stepInformation1 = new StepInformation(stepInstruction.step(), new ArrayList<>()); + final StepInformation step2 = new StepInformation(stepInstruction.finishedBefore(), List.of(stepInstruction.step())); + + final List extractedStepInformations = List.of(stepInformation1, step2); + combinedStepInformations.addAll(extractedStepInformations); + }); + + + return combinedStepInformations; + } + + Map> convertInstructionsToSortedSteps(@Nonnull final List stepInstructions) { + List stepInformations = getSteps(stepInstructions); + + Map>> dependenciesByStep = new HashMap<>(); + + for (StepInformation stepInformation: stepInformations + ) { + if (!dependenciesByStep.containsKey(stepInformation.getStep())) { + List> dependencyList = new ArrayList<>(); + +// List informatonsList = stepInformation.getDependsOn().stream().flatMap(x -> x.charValue()).toList(); + + dependencyList.add(stepInformation.getDependsOn()); +// dependencyList.add(informatonsList); + + dependenciesByStep.put(stepInformation.getStep(), dependencyList); + } else { + dependenciesByStep.get(stepInformation.getStep()).add(stepInformation.getDependsOn()); + } + } + +// Map> cleanedList = dependenciesByStep.values().stream().flatMap(List::stream).toList(); +// Map> cleanedList = dependenciesByStep.forEach(x -> { +// x.charValue(); +// }); + + Map> cleanedList = new HashMap<>(); +// +// for (List> characterList: dependenciesByStep.values() +// ) { +//// characterList.stream().flatMap(List::stream).toList(); +// dependenciesByStep.values().stream().flatMap(List::stream).toList(); +// } + +// dependenciesByStep.values().forEach(List::stream); + + for (Map.Entry>> entry: dependenciesByStep.entrySet() + ) { + cleanedList.put(entry.getKey(),entry.getValue().stream().flatMap(List::stream).toList()); + } + + return cleanedList; + } + + + + // public List cleanSteps(@Nonnull final List stepInformations){ +// List cleanedSteps = stepInformations.stream().collect(Collectors.groupingBy(StepInformation::getStep, )) +// +// } +// public List cleanSteps(@Nonnull final List stepInformations) { +// List cleanedSteps = stepInformations.stream() +// +// } } diff --git a/src/main/java/org/haffson/adventofcode/days/day07/SelectedInstructions.java b/src/main/java/org/haffson/adventofcode/days/day07/SelectedInstructions.java index c2d4f09..cecb3a5 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/SelectedInstructions.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/SelectedInstructions.java @@ -80,8 +80,9 @@ public void setNextStepInstructionByAlphabeticalOrder() { } } } -//public void setNextStepInstructionByAlphabeticalOrder() { -// sortInstructionsAlphabeticalByFinishedBefore(); +//public void setNextStepInstructionByAlphabeticalOrder(@Nonnull final List availableStepInstructions) { +// List sortedInstructions = sortInstructionsAlphabeticalByFinishedBefore(availableStepInstructions); +// // for (int i = 0; i < getAmountOfAvailableStepInstructions(); i++) { // if (isNextStepInstruction(i)) { // setNextStepInstruction(i); @@ -91,6 +92,13 @@ public void setNextStepInstructionByAlphabeticalOrder() { // } //} +// private List sortInstructionsAlphabeticalByFinishedBefore() { +// return availableStepInstructions +// .stream() +// .sorted(Comparator.comparing(StepInstruction::finishedBefore)) +// .toList(); +// } + private void sortInstructionsAlphabeticalByFinishedBefore() { this.availableStepInstructions = availableStepInstructions .stream() diff --git a/src/main/java/org/haffson/adventofcode/days/day07/StepInformation.java b/src/main/java/org/haffson/adventofcode/days/day07/StepInformation.java new file mode 100644 index 0000000..43ecc91 --- /dev/null +++ b/src/main/java/org/haffson/adventofcode/days/day07/StepInformation.java @@ -0,0 +1,81 @@ +package org.haffson.adventofcode.days.day07; + +import javax.annotation.Nonnull; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +import static java.util.Objects.requireNonNull; + +public final class StepInformation { + private final char step; + + private final List dependsOn; + + public StepInformation(final char step, @Nonnull final List dependsOn) { + this.step = step; + this.dependsOn = dependsOn; + } + + public StepInformation(final char step) { + this.step = step; + this.dependsOn = new ArrayList<>(); + } + + public char getStep() { + return step; + } + + public List getDependsOn() { + return dependsOn; + } + +// @Nonnull +// public List getSteps (@Nonnull final List stepInstructions) { +// requireNonNull(stepInstructions, "stepInstructions"); +// +// final List combinedStepInformations = new ArrayList<>(); +// +// stepInstructions.forEach(stepInstruction -> { +// final StepInformation stepInformation1 = new StepInformation(stepInstruction.step(), new ArrayList<>()); +// final StepInformation step2 = new StepInformation(stepInstruction.finishedBefore(), List.of(stepInstruction.step())); +// +// final List extractedStepInformations = List.of(stepInformation1, step2); +// combinedStepInformations.addAll(extractedStepInformations); +// }); +// +// +// return combinedStepInformations; +// } + +// public char step() { +// return step; +// } +// +// @Nonnull +// public List dependsOn() { +// return dependsOn; +// } + + @Override + public boolean equals(final Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + final var that = (StepInformation) obj; + return this.step == that.step && + Objects.equals(this.dependsOn, that.dependsOn); + } + + @Override + public int hashCode() { + return Objects.hash(step, dependsOn); + } + + @Override + public String toString() { + return "Step[" + + "step=" + step + ", " + + "dependsOn=" + dependsOn + ']'; + } + +} diff --git a/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java b/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java index 297a285..a7ffd0f 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java @@ -20,14 +20,8 @@ public StepSorter(@Nonnull final List stepInstructions) { public String getSortedSteps() { initialiseStarting(); -// for (int i = 0; i < selectedInstructions.getAmountOfInstructions(); i++) { selectedInstructions.getStepInstructions().forEach(stepInstruction -> { addNextStepToResult(); - -// setAvailableStepInstructions(); -// selectedInstructions.setNextStepInstructionByAlphabeticalOrder(); -// setNextStepToCheck(); -// addStepToResult(); }); return sortedSteps.getSequenceAsString(); @@ -37,6 +31,7 @@ private void addNextStepToResult() { // final List availableStepInstructions = getAvailableStepInstructions(); setAvailableStepInstructions(); +// selectedInstructions.setNextStepInstructionByAlphabeticalOrder(availableStepInstructions); selectedInstructions.setNextStepInstructionByAlphabeticalOrder(); setNextStepToCheck(); diff --git a/src/test/java/org/haffson/adventofcode/days/day07/Day07Test.java b/src/test/java/org/haffson/adventofcode/days/day07/Day07Test.java index 58d6af5..653e2ab 100644 --- a/src/test/java/org/haffson/adventofcode/days/day07/Day07Test.java +++ b/src/test/java/org/haffson/adventofcode/days/day07/Day07Test.java @@ -5,7 +5,10 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -159,4 +162,79 @@ void test_firstPart_returnsExpectedResult() { assertThat(actualResult).isEqualTo(expectedResult); } +// @Test +// void test_getInstructions(){ +// //arrange +// final FileReaders fileReaders = mock(FileReaders.class); +// +// when(fileReaders.getInputList("src/main/resources/puzzle_input/day7_input.txt")) +// .thenReturn(List.of( +// "Step C must be finished before step A can begin.", +// "Step C must be finished before step F can begin.", +// "Step A must be finished before step B can begin.", +// "Step A must be finished before step D can begin.", +// "Step B must be finished before step E can begin.", +// "Step D must be finished before step E can begin.", +// "Step F must be finished before step E can begin." +// )); +// +// final List expectedResult = List.of( +// new StepInstruction('C','A'), +// new StepInstruction('C','F'), +// new StepInstruction('A','B'), +// new StepInstruction('A','D'), +// new StepInstruction('B','E'), +// new StepInstruction('D','E'), +// new StepInstruction('F','E')); +// +// //act +// +// final List actualResult = day07.getInstructions() +// +// //assert +// assertThat() +// } + + @Test + void test_convertSteps(){ + //arrange + final List stepInstructions = List.of( + new StepInstruction('C','A'), + new StepInstruction('C','F'), + new StepInstruction('A','B'), + new StepInstruction('A','D'), + new StepInstruction('B','E'), + new StepInstruction('D','E'), + new StepInstruction('F','E')); + + final List expectedResult = new ArrayList<>(); + + //act + + final List actualResult = day07.convertInstructionsToSteps(stepInstructions); + //assert + assertThat(actualResult).isEqualTo(expectedResult); + } + + @Test + void test_convertSortedSteps(){ + //arrange + final List stepInstructions = List.of( + new StepInstruction('C','A'), + new StepInstruction('C','F'), + new StepInstruction('A','B'), + new StepInstruction('A','D'), + new StepInstruction('B','E'), + new StepInstruction('D','E'), + new StepInstruction('F','E')); + + final Map> expectedResult = new HashMap<>(); + + //act + + final Map> actualResult = day07.convertInstructionsToSortedSteps(stepInstructions); + //assert + assertThat(actualResult).isEqualTo(expectedResult); + } + } From 67c84afa2cf9d92aee5f8135e5f802603a9c5ff2 Mon Sep 17 00:00:00 2001 From: PascalWo Date: Wed, 31 Aug 2022 17:10:05 +0200 Subject: [PATCH 14/19] Refactored to new Step Object Model --- .../adventofcode/days/day07/Day07.java | 89 ++++------- .../days/day07/SelectedInstructions.java | 144 ------------------ .../days/day07/SelectedSteps.java | 48 ------ .../adventofcode/days/day07/SortedSteps.java | 33 ++-- .../adventofcode/days/day07/Starter.java | 34 ++--- .../haffson/adventofcode/days/day07/Step.java | 57 +++++++ .../days/day07/StepInformation.java | 81 ---------- .../adventofcode/days/day07/StepSorter.java | 104 ++++--------- .../adventofcode/days/day07/Day07Test.java | 67 +++++--- .../days/day07/StepSorterTest.java | 25 +-- .../adventofcode/days/day07/StepTest.java | 36 +++++ 11 files changed, 246 insertions(+), 472 deletions(-) delete mode 100644 src/main/java/org/haffson/adventofcode/days/day07/SelectedInstructions.java delete mode 100644 src/main/java/org/haffson/adventofcode/days/day07/SelectedSteps.java create mode 100644 src/main/java/org/haffson/adventofcode/days/day07/Step.java delete mode 100644 src/main/java/org/haffson/adventofcode/days/day07/StepInformation.java create mode 100644 src/test/java/org/haffson/adventofcode/days/day07/StepTest.java diff --git a/src/main/java/org/haffson/adventofcode/days/day07/Day07.java b/src/main/java/org/haffson/adventofcode/days/day07/Day07.java index 6cffb3e..d2f0856 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/Day07.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/Day07.java @@ -11,7 +11,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; import static java.util.Objects.requireNonNull; @@ -75,94 +74,70 @@ public String secondPart() { @Nonnull private String calculateFirstPart(@Nonnull final List inputStringList) { final List inputList = StepInstruction.of(inputStringList); - final StepSorter stepSorter = new StepSorter(inputList); + final List steps = getSteps(inputList); + final StepSorter stepSorter = new StepSorter(); - return stepSorter.getSortedSteps(); + return stepSorter.getSortedSteps(steps); } private long calculateSecondPart(@Nonnull final List inputStringList) { return 0; } - List getInstructions(@Nonnull final List inputStringList) { - return StepInstruction.of(inputStringList); - } - - List convertInstructionsToSteps(@Nonnull final List stepInstructions) { - return getSteps(stepInstructions); + @Nonnull + private List getSteps(@Nonnull final List instructions) { + final Map> dependenciesByStep = convertInstructionsToSortedSteps(instructions); + return Step.of(dependenciesByStep); } @Nonnull - public List getSteps(@Nonnull final List stepInstructions) { + private List convertInstructionsToSteps(@Nonnull final List stepInstructions) { requireNonNull(stepInstructions, "stepInstructions"); - final List combinedStepInformations = new ArrayList<>(); + final List combinedSteps = new ArrayList<>(); stepInstructions.forEach(stepInstruction -> { - final StepInformation stepInformation1 = new StepInformation(stepInstruction.step(), new ArrayList<>()); - final StepInformation step2 = new StepInformation(stepInstruction.finishedBefore(), List.of(stepInstruction.step())); + final Step step1 = new Step(stepInstruction.step(), new ArrayList<>()); + final Step step2 = new Step(stepInstruction.finishedBefore(), List.of(stepInstruction.step())); - final List extractedStepInformations = List.of(stepInformation1, step2); - combinedStepInformations.addAll(extractedStepInformations); + final List extractedSteps = List.of(step1, step2); + combinedSteps.addAll(extractedSteps); }); - return combinedStepInformations; + return combinedSteps; } - Map> convertInstructionsToSortedSteps(@Nonnull final List stepInstructions) { - List stepInformations = getSteps(stepInstructions); + Map> convertInstructionsToSortedSteps(@Nonnull final List stepInstructions) { + final List steps = convertInstructionsToSteps(stepInstructions); - Map>> dependenciesByStep = new HashMap<>(); + final Map>> dependenciesByStep = new HashMap<>(); - for (StepInformation stepInformation: stepInformations - ) { - if (!dependenciesByStep.containsKey(stepInformation.getStep())) { - List> dependencyList = new ArrayList<>(); + for (final Step step : steps + ) { + if (!dependenciesByStep.containsKey(step.getStepName())) { + final List> dependencyList = new ArrayList<>(); -// List informatonsList = stepInformation.getDependsOn().stream().flatMap(x -> x.charValue()).toList(); + dependencyList.add(step.getDependsOn()); - dependencyList.add(stepInformation.getDependsOn()); -// dependencyList.add(informatonsList); - - dependenciesByStep.put(stepInformation.getStep(), dependencyList); + dependenciesByStep.put(step.getStepName(), dependencyList); } else { - dependenciesByStep.get(stepInformation.getStep()).add(stepInformation.getDependsOn()); + dependenciesByStep.get(step.getStepName()).add(step.getDependsOn()); } } -// Map> cleanedList = dependenciesByStep.values().stream().flatMap(List::stream).toList(); -// Map> cleanedList = dependenciesByStep.forEach(x -> { -// x.charValue(); -// }); - - Map> cleanedList = new HashMap<>(); -// -// for (List> characterList: dependenciesByStep.values() -// ) { -//// characterList.stream().flatMap(List::stream).toList(); -// dependenciesByStep.values().stream().flatMap(List::stream).toList(); -// } + return duplicateFreeDependenciesByStep(dependenciesByStep); + } -// dependenciesByStep.values().forEach(List::stream); + private Map> duplicateFreeDependenciesByStep(@Nonnull final Map>> duplicatedDependenciesByStep) { + final Map> dependenciesByStep = new HashMap<>(); - for (Map.Entry>> entry: dependenciesByStep.entrySet() - ) { - cleanedList.put(entry.getKey(),entry.getValue().stream().flatMap(List::stream).toList()); + for (final Map.Entry>> entry : duplicatedDependenciesByStep.entrySet() + ) { + dependenciesByStep.put(entry.getKey(), entry.getValue().stream().flatMap(List::stream).toList()); } - return cleanedList; + return dependenciesByStep; } - - - - // public List cleanSteps(@Nonnull final List stepInformations){ -// List cleanedSteps = stepInformations.stream().collect(Collectors.groupingBy(StepInformation::getStep, )) -// -// } -// public List cleanSteps(@Nonnull final List stepInformations) { -// List cleanedSteps = stepInformations.stream() -// -// } } diff --git a/src/main/java/org/haffson/adventofcode/days/day07/SelectedInstructions.java b/src/main/java/org/haffson/adventofcode/days/day07/SelectedInstructions.java deleted file mode 100644 index cecb3a5..0000000 --- a/src/main/java/org/haffson/adventofcode/days/day07/SelectedInstructions.java +++ /dev/null @@ -1,144 +0,0 @@ -package org.haffson.adventofcode.days.day07; - -import javax.annotation.Nonnull; -import java.util.*; - -import static java.util.Objects.requireNonNull; - -public class SelectedInstructions { - - @Nonnull - private final List stepInstructions; - @Nonnull - private List availableStepInstructions = new ArrayList<>(); - @Nonnull - private List availableStepInstructionsNotUsed = new ArrayList<>(); - private StepInstruction nextStepInstruction; - @Nonnull - private final SortedSteps sortedSteps; - - public SelectedInstructions(@Nonnull final List stepInstructions, @Nonnull final SortedSteps sortedSteps) { - this.stepInstructions = requireNonNull(stepInstructions, "stepInstructions"); - this.sortedSteps = requireNonNull(sortedSteps, "sortedSteps"); - } - - @Nonnull - public List getStepInstructions() { - return stepInstructions; - } - - public StepInstruction getNextStepInstruction() { - return nextStepInstruction; - } - - public int getAmountOfInstructions() { - return stepInstructions.size(); - } - - public void setAvailableStarterOptions(@Nonnull final Starter starter) { - for (final char stepToCompare : starter.getStartingSteps()) { - - availableStepInstructionsNotUsed.addAll(getAvailableStepInstructions(stepToCompare)); - } - } - - @Nonnull - private List getAvailableStepInstructions(final char stepToCompare) { - return List.copyOf(stepInstructions).stream() - .filter(stepInstruction -> stepToCompare == stepInstruction.step()). - toList(); - } - - public void setAvailableStepInstructions(final char stepToCompare) { - final Set availableInstructions = new HashSet<>(); - - availableInstructions.addAll(getAvailableStepInstructions(stepToCompare)); - availableInstructions.addAll(availableStepInstructionsNotUsed); - - this.availableStepInstructions = new ArrayList<>(availableInstructions); - } -//public List setAvailableStepInstructions(final char stepToCompare) { -// final Set availableInstructions = new HashSet<>(); -// -// availableInstructions.addAll(getAvailableStepInstructions(stepToCompare)); -// availableInstructions.addAll(availableStepInstructionsNotUsed); -// -// return new ArrayList<>(availableInstructions); -//} - - public int getAmountOfAvailableStepInstructions() { - return availableStepInstructions.size(); - } - - public void setNextStepInstructionByAlphabeticalOrder() { - sortInstructionsAlphabeticalByFinishedBefore(); - for (int i = 0; i < getAmountOfAvailableStepInstructions(); i++) { - if (isNextStepInstruction(i)) { - setNextStepInstruction(i); - setUnusedStepInstructions(i); - break; - } - } - } -//public void setNextStepInstructionByAlphabeticalOrder(@Nonnull final List availableStepInstructions) { -// List sortedInstructions = sortInstructionsAlphabeticalByFinishedBefore(availableStepInstructions); -// -// for (int i = 0; i < getAmountOfAvailableStepInstructions(); i++) { -// if (isNextStepInstruction(i)) { -// setNextStepInstruction(i); -// setUnusedStepInstructions(i); -// break; -// } -// } -//} - -// private List sortInstructionsAlphabeticalByFinishedBefore() { -// return availableStepInstructions -// .stream() -// .sorted(Comparator.comparing(StepInstruction::finishedBefore)) -// .toList(); -// } - - private void sortInstructionsAlphabeticalByFinishedBefore() { - this.availableStepInstructions = availableStepInstructions - .stream() - .sorted(Comparator.comparing(StepInstruction::finishedBefore)) - .toList(); - } - - private boolean isNextStepInstruction(final int i) { - final StepInstruction possibleNextInstruction = availableStepInstructions.get(i); - - return isPrerequisiteComplete(possibleNextInstruction); - } - - private boolean isPrerequisiteComplete(@Nonnull final StepInstruction instructionToCheck) { - final char stepToCheck = instructionToCheck.finishedBefore(); - - if (sortedSteps.stepIsAlreadyUsed(stepToCheck)) { - return false; - } - final List stepsNeededToBeCompleted = getStepsNeedToBeCompleted(stepToCheck); - - return sortedSteps.isEveryNeededStepCompleted(stepsNeededToBeCompleted); - } - - @Nonnull - private List getStepsNeedToBeCompleted(final char stepToCheck) { - return List.copyOf(stepInstructions) - .stream() - .filter(stepInstruction -> stepToCheck == stepInstruction.finishedBefore()) - .map(StepInstruction::step) - .toList(); - } - - private void setNextStepInstruction(final int i) { - this.nextStepInstruction = availableStepInstructions.get(i); - } - - private void setUnusedStepInstructions(final int i) { - final List stepInstructionsNotUsed = new ArrayList<>(availableStepInstructions); - stepInstructionsNotUsed.remove(i); - this.availableStepInstructionsNotUsed = stepInstructionsNotUsed; - } -} diff --git a/src/main/java/org/haffson/adventofcode/days/day07/SelectedSteps.java b/src/main/java/org/haffson/adventofcode/days/day07/SelectedSteps.java deleted file mode 100644 index 881656a..0000000 --- a/src/main/java/org/haffson/adventofcode/days/day07/SelectedSteps.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.haffson.adventofcode.days.day07; - -public class SelectedSteps { - - private char leastStep; - private char nextStepToCheck; - private char stepWhenInstructionIsEmpty; - private char stepWhenInstructionIsDuplicated; - - public SelectedSteps() { - this.leastStep = Character.MIN_VALUE; - this.nextStepToCheck = Character.MIN_VALUE; - this.stepWhenInstructionIsEmpty = Character.MIN_VALUE; - this.stepWhenInstructionIsDuplicated = Character.MIN_VALUE; - } - - public char getLeastStep() { - return leastStep; - } - - public char getNextStepToCheck() { - return nextStepToCheck; - } - - public void setNextStepToCheck(final char nextStepToCheck) { - this.nextStepToCheck = nextStepToCheck; - } - - public char getStepWhenInstructionIsEmpty() { - return stepWhenInstructionIsEmpty; - } - - public void setStepWhenInstructionIsEmpty(final char stepWhenInstructionIsEmpty) { - this.stepWhenInstructionIsEmpty = stepWhenInstructionIsEmpty; - } - - public char getStepWhenInstructionIsDuplicated() { - return stepWhenInstructionIsDuplicated; - } - - public void setStepWhenInstructionIsDuplicated(final char stepWhenInstructionIsDuplicated) { - this.stepWhenInstructionIsDuplicated = stepWhenInstructionIsDuplicated; - } - - void setLeastStep() { - this.leastStep = this.getNextStepToCheck(); - } -} diff --git a/src/main/java/org/haffson/adventofcode/days/day07/SortedSteps.java b/src/main/java/org/haffson/adventofcode/days/day07/SortedSteps.java index f6dd8b9..bddfab7 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/SortedSteps.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/SortedSteps.java @@ -2,23 +2,27 @@ import javax.annotation.Nonnull; import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; import java.util.List; import java.util.stream.Collectors; public class SortedSteps { - private final List stepSequence; + private final List characterSequence; + private final List stepSequence; public SortedSteps() { + this.characterSequence = new ArrayList<>(); this.stepSequence = new ArrayList<>(); } - public List getStepSequence() { - return Collections.unmodifiableList(stepSequence); + public List getCharacterSequence() { + final List characters = new ArrayList<>(); + stepSequence.forEach(step -> { + characters.add(step.getStepName()); + }); + return characters; } - public void addStep(final char nextStepToCheck) { + public void addStep(final Step nextStepToCheck) { if (isStepToCheckEmpty(nextStepToCheck)) { return; } @@ -27,20 +31,15 @@ public void addStep(final char nextStepToCheck) { } } - private boolean isStepToCheckEmpty(final char stepToCheck) { - return stepToCheck == Character.MIN_VALUE; + private boolean isStepToCheckEmpty(final Step stepToCheck) { + return stepToCheck.getStepName() == Character.MIN_VALUE; } @Nonnull - public String getSequenceAsString() { - return stepSequence.stream().map(String::valueOf).collect(Collectors.joining()); + public String getStepsAsString() { + List characters = getCharacterSequence(); + return characters.stream().map(String::valueOf).collect(Collectors.joining()); } +} - public boolean stepIsAlreadyUsed(final char stepToCheck) { - return getStepSequence().contains(stepToCheck); - } - public boolean isEveryNeededStepCompleted(@Nonnull final List stepsNeededToBeCompleted) { - return new HashSet<>(getStepSequence()).containsAll(stepsNeededToBeCompleted); - } -} diff --git a/src/main/java/org/haffson/adventofcode/days/day07/Starter.java b/src/main/java/org/haffson/adventofcode/days/day07/Starter.java index ef5bee2..66333fc 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/Starter.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/Starter.java @@ -2,39 +2,29 @@ import javax.annotation.Nonnull; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; -import java.util.Set; -import static java.util.Objects.requireNonNull; public class Starter { - List startingSteps; - private final List stepInstructions; - public Starter(@Nonnull final List stepInstructions) { - this.stepInstructions = requireNonNull(stepInstructions, "stepInstructions"); - } - - public void setStartingSteps() { - final List steps = new ArrayList<>(); - this.stepInstructions.forEach(stepInstruction -> steps.add(stepInstruction.step())); - - final List stepsFinishedBefore = new ArrayList<>(); - this.stepInstructions.forEach(stepInstruction -> stepsFinishedBefore.add(stepInstruction.finishedBefore())); + private List startingSteps; - final List stepsWithoutPreCondition = new ArrayList<>(steps); - stepsWithoutPreCondition.removeAll(stepsFinishedBefore); - final Set stepsWithoutPreConditionDuplicateFree = new HashSet<>(stepsWithoutPreCondition); - - this.startingSteps = new ArrayList<>(stepsWithoutPreConditionDuplicateFree); + public Starter() { + this.startingSteps = new ArrayList<>(); } - public List getStartingSteps() { + public List getStartingSteps(@Nonnull final List steps) { + final List startingSteps = new ArrayList<>(); + steps.forEach(step -> { + if (step.getDependsOn().isEmpty()) { + startingSteps.add(step); + } + }); + return startingSteps; } - public char getStartingStep() { + public Step getStartingStep(@Nonnull final List startingSteps) { return startingSteps.get(0); } } diff --git a/src/main/java/org/haffson/adventofcode/days/day07/Step.java b/src/main/java/org/haffson/adventofcode/days/day07/Step.java new file mode 100644 index 0000000..4a31b28 --- /dev/null +++ b/src/main/java/org/haffson/adventofcode/days/day07/Step.java @@ -0,0 +1,57 @@ +package org.haffson.adventofcode.days.day07; + +import javax.annotation.Nonnull; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +public final class Step { + private final char stepName; + + private final List dependsOn; + + public Step(final char stepName, @Nonnull final List dependsOn) { + this.stepName = stepName; + this.dependsOn = dependsOn; + } + + public static List of(@Nonnull final Map> dependenciesByStep) { + return dependenciesByStep.entrySet().stream().map(entry -> new Step(entry.getKey(), entry.getValue())).toList(); + + } + + public Step(final char stepName) { + this.stepName = stepName; + this.dependsOn = new ArrayList<>(); + } + + public char getStepName() { + return stepName; + } + + public List getDependsOn() { + return dependsOn; + } + + @Override + public boolean equals(final Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + final Step step = (Step) o; + return stepName == step.stepName && Objects.equals(dependsOn, step.dependsOn); + } + + @Override + public int hashCode() { + return Objects.hash(stepName, dependsOn); + } + + @Override + public String toString() { + return "Step{" + + "stepName=" + stepName + + ", dependsOn=" + dependsOn + + '}'; + } +} diff --git a/src/main/java/org/haffson/adventofcode/days/day07/StepInformation.java b/src/main/java/org/haffson/adventofcode/days/day07/StepInformation.java deleted file mode 100644 index 43ecc91..0000000 --- a/src/main/java/org/haffson/adventofcode/days/day07/StepInformation.java +++ /dev/null @@ -1,81 +0,0 @@ -package org.haffson.adventofcode.days.day07; - -import javax.annotation.Nonnull; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -import static java.util.Objects.requireNonNull; - -public final class StepInformation { - private final char step; - - private final List dependsOn; - - public StepInformation(final char step, @Nonnull final List dependsOn) { - this.step = step; - this.dependsOn = dependsOn; - } - - public StepInformation(final char step) { - this.step = step; - this.dependsOn = new ArrayList<>(); - } - - public char getStep() { - return step; - } - - public List getDependsOn() { - return dependsOn; - } - -// @Nonnull -// public List getSteps (@Nonnull final List stepInstructions) { -// requireNonNull(stepInstructions, "stepInstructions"); -// -// final List combinedStepInformations = new ArrayList<>(); -// -// stepInstructions.forEach(stepInstruction -> { -// final StepInformation stepInformation1 = new StepInformation(stepInstruction.step(), new ArrayList<>()); -// final StepInformation step2 = new StepInformation(stepInstruction.finishedBefore(), List.of(stepInstruction.step())); -// -// final List extractedStepInformations = List.of(stepInformation1, step2); -// combinedStepInformations.addAll(extractedStepInformations); -// }); -// -// -// return combinedStepInformations; -// } - -// public char step() { -// return step; -// } -// -// @Nonnull -// public List dependsOn() { -// return dependsOn; -// } - - @Override - public boolean equals(final Object obj) { - if (obj == this) return true; - if (obj == null || obj.getClass() != this.getClass()) return false; - final var that = (StepInformation) obj; - return this.step == that.step && - Objects.equals(this.dependsOn, that.dependsOn); - } - - @Override - public int hashCode() { - return Objects.hash(step, dependsOn); - } - - @Override - public String toString() { - return "Step[" + - "step=" + step + ", " + - "dependsOn=" + dependsOn + ']'; - } - -} diff --git a/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java b/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java index a7ffd0f..83a1b25 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java @@ -2,96 +2,54 @@ import javax.annotation.Nonnull; import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashSet; import java.util.List; public class StepSorter { private final SortedSteps sortedSteps; - private final SelectedSteps selectedSteps; + private final Starter starter; - private final SelectedInstructions selectedInstructions; - public StepSorter(@Nonnull final List stepInstructions) { + public StepSorter() { this.sortedSteps = new SortedSteps(); - this.selectedInstructions = new SelectedInstructions(stepInstructions, sortedSteps); - this.selectedSteps = new SelectedSteps(); - this.starter = new Starter(stepInstructions); + this.starter = new Starter(); } - public String getSortedSteps() { - initialiseStarting(); + public String getSortedSteps(@Nonnull final List stepsInput) { + + final List steps = new ArrayList<>(stepsInput); + final Step startingStep = getStartingStep(steps); + sortedSteps.addStep(startingStep); + steps.remove(startingStep); + final List stepsWithoutStart = new ArrayList<>(steps); - selectedInstructions.getStepInstructions().forEach(stepInstruction -> { - addNextStepToResult(); + stepsWithoutStart.forEach(step -> { + final List availableSteps = getAvailableSteps(steps); + final List sortedAvailableSteps = new ArrayList<>(availableSteps); + sortedAvailableSteps.sort(Comparator.comparing(Step::getStepName)); + final Step nextStep = sortedAvailableSteps.get(0); + sortedSteps.addStep(nextStep); + steps.remove(nextStep); }); - return sortedSteps.getSequenceAsString(); + return sortedSteps.getStepsAsString(); } - private void addNextStepToResult() { -// final List availableStepInstructions = getAvailableStepInstructions(); - setAvailableStepInstructions(); - -// selectedInstructions.setNextStepInstructionByAlphabeticalOrder(availableStepInstructions); - selectedInstructions.setNextStepInstructionByAlphabeticalOrder(); - - setNextStepToCheck(); - - addStepToResult(); - } - private void setAvailableStepInstructions(){ - selectedInstructions.setAvailableStepInstructions(selectedSteps.getNextStepToCheck()); + private Step getStartingStep(@Nonnull final List steps) { + final List startingSteps = starter.getStartingSteps(steps); + startingSteps.sort(Comparator.comparing(Step::getStepName)); + return startingSteps.get(0); } -// private List getAvailableStepInstructions(){ -// return selectedInstructions.setAvailableStepInstructions(selectedSteps.getNextStepToCheck()); -// } + private List getAvailableSteps(@Nonnull final List steps) { + final List availableSteps = new ArrayList<>(); - private void initialiseStarting() { - starter.setStartingSteps(); - selectedInstructions.setAvailableStarterOptions(starter); - sortedSteps.addStep(starter.getStartingStep()); - selectedSteps.setNextStepToCheck(starter.getStartingStep()); - } - - private void setNextStepToCheck() { - if (isNextStepInstructionEmpty()) { - selectedSteps.setNextStepToCheck(selectedInstructions.getNextStepInstruction().finishedBefore()); - if (selectedSteps.getNextStepToCheck() == selectedSteps.getLeastStep()) { - setNextStepWhenDuplicate(); - selectedSteps.setNextStepToCheck(selectedSteps.getStepWhenInstructionIsDuplicated()); + steps.forEach(step -> { + if (new HashSet<>(sortedSteps.getCharacterSequence()).containsAll(step.getDependsOn())) { + availableSteps.add(step); } - } else { - setNextStepWhenEmpty(); - selectedSteps.setNextStepToCheck(selectedSteps.getStepWhenInstructionIsEmpty()); - } - } - - private boolean isNextStepInstructionEmpty(){ - return selectedInstructions.getNextStepInstruction() != null; - } - - private void setNextStepWhenDuplicate() { - if (!getAvailableStarterSteps().isEmpty()) { - selectedSteps.setStepWhenInstructionIsDuplicated(getAvailableStarterSteps().get(0)); - } - } - - private void setNextStepWhenEmpty() { - selectedSteps.setStepWhenInstructionIsEmpty(getAvailableStarterSteps().get(0)); - } - - @Nonnull - private List getAvailableStarterSteps() { - final List starterSteps = new ArrayList<>(starter.getStartingSteps()); - final List actualSteps = new ArrayList<>(sortedSteps.getStepSequence()); - - starterSteps.removeAll(actualSteps); - - return starterSteps; - } - - private void addStepToResult() { - sortedSteps.addStep(selectedSteps.getNextStepToCheck()); - selectedSteps.setLeastStep(); + }); + return availableSteps; } } diff --git a/src/test/java/org/haffson/adventofcode/days/day07/Day07Test.java b/src/test/java/org/haffson/adventofcode/days/day07/Day07Test.java index 653e2ab..ae154e1 100644 --- a/src/test/java/org/haffson/adventofcode/days/day07/Day07Test.java +++ b/src/test/java/org/haffson/adventofcode/days/day07/Day07Test.java @@ -195,26 +195,26 @@ void test_firstPart_returnsExpectedResult() { // assertThat() // } - @Test - void test_convertSteps(){ - //arrange - final List stepInstructions = List.of( - new StepInstruction('C','A'), - new StepInstruction('C','F'), - new StepInstruction('A','B'), - new StepInstruction('A','D'), - new StepInstruction('B','E'), - new StepInstruction('D','E'), - new StepInstruction('F','E')); - - final List expectedResult = new ArrayList<>(); - - //act - - final List actualResult = day07.convertInstructionsToSteps(stepInstructions); - //assert - assertThat(actualResult).isEqualTo(expectedResult); - } +// @Test +// void test_convertSteps(){ +// //arrange +// final List stepInstructions = List.of( +// new StepInstruction('C','A'), +// new StepInstruction('C','F'), +// new StepInstruction('A','B'), +// new StepInstruction('A','D'), +// new StepInstruction('B','E'), +// new StepInstruction('D','E'), +// new StepInstruction('F','E')); +// +// final List expectedResult = new ArrayList<>(); +// +// //act +// +// final List actualResult = day07.convertInstructionsToSteps(stepInstructions); +// //assert +// assertThat(actualResult).isEqualTo(expectedResult); +// } @Test void test_convertSortedSteps(){ @@ -228,7 +228,13 @@ void test_convertSortedSteps(){ new StepInstruction('D','E'), new StepInstruction('F','E')); - final Map> expectedResult = new HashMap<>(); + final Map> expectedResult = Map.of('A',List.of('C'), + 'F',List.of('C'), + 'B',List.of('A'), + 'D',List.of('A'), + 'E',List.of('B','D','F'), + 'C',List.of()); + //act @@ -237,4 +243,23 @@ void test_convertSortedSteps(){ assertThat(actualResult).isEqualTo(expectedResult); } +// @Test +// void test_convertMapToSteps(){ +// //arrange +// final Map> inputMap = Map.of('A',List.of('C'), +// 'F',List.of('C'), +// 'B',List.of('A'), +// 'D',List.of('A'), +// 'E',List.of('B','D','F'), +// 'C',List.of()); +// +// final List expectedResult = List.of(new Step()) +// +// //act +// +// final Map> actualResult = day07.convertInstructionsToSortedSteps(stepInstructions); +// //assert +// assertThat(actualResult).isEqualTo(expectedResult); +// } + } diff --git a/src/test/java/org/haffson/adventofcode/days/day07/StepSorterTest.java b/src/test/java/org/haffson/adventofcode/days/day07/StepSorterTest.java index 2ac7579..6933ff9 100644 --- a/src/test/java/org/haffson/adventofcode/days/day07/StepSorterTest.java +++ b/src/test/java/org/haffson/adventofcode/days/day07/StepSorterTest.java @@ -33,20 +33,27 @@ void setUp() { @Test void getSortedSteps_shouldReturnSortedStepsAsString() { //arrange - final List stepInstructions = List.of(new StepInstruction('C', 'A'), - new StepInstruction('C', 'F'), - new StepInstruction('A', 'B'), - new StepInstruction('A', 'D'), - new StepInstruction('B', 'E'), - new StepInstruction('D', 'E'), - new StepInstruction('F', 'E')); +// final List stepInstructions = List.of(new StepInstruction('C', 'A'), +// new StepInstruction('C', 'F'), +// new StepInstruction('A', 'B'), +// new StepInstruction('A', 'D'), +// new StepInstruction('B', 'E'), +// new StepInstruction('D', 'E'), +// new StepInstruction('F', 'E')); + + final List steps = List.of(new Step('A', List.of('C')), + new Step('F', List.of('C')), + new Step('B', List.of('A')), + new Step('D', List.of('A')), + new Step('E', List.of('B', 'D', 'F')), + new Step('C')); - final StepSorter stepSorter = new StepSorter(stepInstructions); + final StepSorter stepSorter = new StepSorter(); final String expectedResult = "CABDFE"; //act - final String actualResult = stepSorter.getSortedSteps(); + final String actualResult = stepSorter.getSortedSteps(steps); //assert assertThat(actualResult).isEqualTo(expectedResult); } diff --git a/src/test/java/org/haffson/adventofcode/days/day07/StepTest.java b/src/test/java/org/haffson/adventofcode/days/day07/StepTest.java new file mode 100644 index 0000000..4ca4953 --- /dev/null +++ b/src/test/java/org/haffson/adventofcode/days/day07/StepTest.java @@ -0,0 +1,36 @@ +package org.haffson.adventofcode.days.day07; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.List; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +class StepTest { + + @DisplayName("of() should return new List of Steps") + @Test + void of_returnListOfSteps() { + //arrange + final Map> inputMap = Map.of('A', List.of('C'), + 'F', List.of('C'), + 'B', List.of('A'), + 'D', List.of('A'), + 'E', List.of('B', 'D', 'F'), + 'C', List.of()); + + final List expectedResult = List.of(new Step('A', List.of('C')), + new Step('F', List.of('C')), + new Step('B', List.of('A')), + new Step('D', List.of('A')), + new Step('E', List.of('B', 'D', 'F')), + new Step('C')); + //act + final List actualResult = Step.of(inputMap); + //assert + assertThat(actualResult).usingRecursiveComparison().ignoringCollectionOrder().isEqualTo(expectedResult); + } +} From cf013c020e497ac973263a7b4c1cf547e4e6e7b9 Mon Sep 17 00:00:00 2001 From: PascalWo Date: Thu, 1 Sep 2022 17:26:38 +0200 Subject: [PATCH 15/19] added more null safety and reduces boiler code --- .../adventofcode/days/day07/Day07.java | 53 ++++---- .../adventofcode/days/day07/SortedSteps.java | 18 +-- .../adventofcode/days/day07/Starter.java | 30 ----- .../haffson/adventofcode/days/day07/Step.java | 16 ++- .../adventofcode/days/day07/StepSorter.java | 47 +++++-- .../adventofcode/days/day07/Day07Test.java | 116 ------------------ 6 files changed, 82 insertions(+), 198 deletions(-) delete mode 100644 src/main/java/org/haffson/adventofcode/days/day07/Starter.java diff --git a/src/main/java/org/haffson/adventofcode/days/day07/Day07.java b/src/main/java/org/haffson/adventofcode/days/day07/Day07.java index d2f0856..bc5d7f3 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/Day07.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/Day07.java @@ -84,7 +84,6 @@ private long calculateSecondPart(@Nonnull final List inputStringList) { return 0; } - @Nonnull private List getSteps(@Nonnull final List instructions) { final Map> dependenciesByStep = convertInstructionsToSortedSteps(instructions); @@ -92,30 +91,14 @@ private List getSteps(@Nonnull final List instructions) { } @Nonnull - private List convertInstructionsToSteps(@Nonnull final List stepInstructions) { + private Map> convertInstructionsToSortedSteps(@Nonnull final List stepInstructions) { requireNonNull(stepInstructions, "stepInstructions"); - final List combinedSteps = new ArrayList<>(); - - stepInstructions.forEach(stepInstruction -> { - final Step step1 = new Step(stepInstruction.step(), new ArrayList<>()); - final Step step2 = new Step(stepInstruction.finishedBefore(), List.of(stepInstruction.step())); - - final List extractedSteps = List.of(step1, step2); - combinedSteps.addAll(extractedSteps); - }); - - - return combinedSteps; - } - - Map> convertInstructionsToSortedSteps(@Nonnull final List stepInstructions) { final List steps = convertInstructionsToSteps(stepInstructions); final Map>> dependenciesByStep = new HashMap<>(); - for (final Step step : steps - ) { + steps.forEach(step -> { if (!dependenciesByStep.containsKey(step.getStepName())) { final List> dependencyList = new ArrayList<>(); @@ -125,18 +108,38 @@ Map> convertInstructionsToSortedSteps(@Nonnull final } else { dependenciesByStep.get(step.getStepName()).add(step.getDependsOn()); } - } + }); return duplicateFreeDependenciesByStep(dependenciesByStep); } - private Map> duplicateFreeDependenciesByStep(@Nonnull final Map>> duplicatedDependenciesByStep) { + + @Nonnull + private List convertInstructionsToSteps(@Nonnull final List stepInstructions) { + requireNonNull(stepInstructions, "stepInstructions"); + + final List completeSteps = new ArrayList<>(); + + stepInstructions.forEach(stepInstruction -> { + final Step step1 = new Step(stepInstruction.step(), new ArrayList<>()); + final Step step2 = new Step(stepInstruction.finishedBefore(), List.of(stepInstruction.step())); + + final List transformedSteps = List.of(step1, step2); + completeSteps.addAll(transformedSteps); + }); + + return completeSteps; + } + + @Nonnull + private Map> duplicateFreeDependenciesByStep( + @Nonnull final Map>> duplicatedDependenciesByStep) { + requireNonNull(duplicatedDependenciesByStep, "duplicatedDependenciesByStep"); + final Map> dependenciesByStep = new HashMap<>(); - for (final Map.Entry>> entry : duplicatedDependenciesByStep.entrySet() - ) { - dependenciesByStep.put(entry.getKey(), entry.getValue().stream().flatMap(List::stream).toList()); - } + duplicatedDependenciesByStep.forEach((stepName, stepDependencies) -> dependenciesByStep + .put(stepName, stepDependencies.stream().flatMap(List::stream).toList())); return dependenciesByStep; } diff --git a/src/main/java/org/haffson/adventofcode/days/day07/SortedSteps.java b/src/main/java/org/haffson/adventofcode/days/day07/SortedSteps.java index bddfab7..72f86c8 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/SortedSteps.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/SortedSteps.java @@ -5,24 +5,23 @@ import java.util.List; import java.util.stream.Collectors; +import static java.util.Objects.requireNonNull; + public class SortedSteps { - private final List characterSequence; private final List stepSequence; public SortedSteps() { - this.characterSequence = new ArrayList<>(); this.stepSequence = new ArrayList<>(); } - + @Nonnull public List getCharacterSequence() { final List characters = new ArrayList<>(); - stepSequence.forEach(step -> { - characters.add(step.getStepName()); - }); + stepSequence.forEach(step -> characters.add(step.getStepName())); return characters; } - public void addStep(final Step nextStepToCheck) { + public void addStep(@Nonnull final Step nextStepToCheck) { + requireNonNull(nextStepToCheck, "nextStepToCheck"); if (isStepToCheckEmpty(nextStepToCheck)) { return; } @@ -31,13 +30,14 @@ public void addStep(final Step nextStepToCheck) { } } - private boolean isStepToCheckEmpty(final Step stepToCheck) { + private boolean isStepToCheckEmpty(@Nonnull final Step stepToCheck) { + requireNonNull(stepToCheck, "stepToCheck"); return stepToCheck.getStepName() == Character.MIN_VALUE; } @Nonnull public String getStepsAsString() { - List characters = getCharacterSequence(); + final List characters = getCharacterSequence(); return characters.stream().map(String::valueOf).collect(Collectors.joining()); } } diff --git a/src/main/java/org/haffson/adventofcode/days/day07/Starter.java b/src/main/java/org/haffson/adventofcode/days/day07/Starter.java deleted file mode 100644 index 66333fc..0000000 --- a/src/main/java/org/haffson/adventofcode/days/day07/Starter.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.haffson.adventofcode.days.day07; - -import javax.annotation.Nonnull; -import java.util.ArrayList; -import java.util.List; - - -public class Starter { - - private List startingSteps; - - public Starter() { - this.startingSteps = new ArrayList<>(); - } - - public List getStartingSteps(@Nonnull final List steps) { - final List startingSteps = new ArrayList<>(); - steps.forEach(step -> { - if (step.getDependsOn().isEmpty()) { - startingSteps.add(step); - } - }); - - return startingSteps; - } - - public Step getStartingStep(@Nonnull final List startingSteps) { - return startingSteps.get(0); - } -} diff --git a/src/main/java/org/haffson/adventofcode/days/day07/Step.java b/src/main/java/org/haffson/adventofcode/days/day07/Step.java index 4a31b28..54eef8d 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/Step.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/Step.java @@ -6,19 +6,17 @@ import java.util.Map; import java.util.Objects; +import static java.util.Objects.requireNonNull; + public final class Step { private final char stepName; + @Nonnull private final List dependsOn; public Step(final char stepName, @Nonnull final List dependsOn) { this.stepName = stepName; - this.dependsOn = dependsOn; - } - - public static List of(@Nonnull final Map> dependenciesByStep) { - return dependenciesByStep.entrySet().stream().map(entry -> new Step(entry.getKey(), entry.getValue())).toList(); - + this.dependsOn = requireNonNull(dependsOn, "dependsOn"); } public Step(final char stepName) { @@ -26,10 +24,16 @@ public Step(final char stepName) { this.dependsOn = new ArrayList<>(); } + public static List of(@Nonnull final Map> dependenciesByStep) { + requireNonNull(dependenciesByStep, "dependenciesByStep"); + return dependenciesByStep.entrySet().stream().map(entry -> new Step(entry.getKey(), entry.getValue())).toList(); + } + public char getStepName() { return stepName; } + @Nonnull public List getDependsOn() { return dependsOn; } diff --git a/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java b/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java index 83a1b25..1b0046f 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java @@ -6,17 +6,19 @@ import java.util.HashSet; import java.util.List; +import static java.util.Objects.requireNonNull; + public class StepSorter { + @Nonnull private final SortedSteps sortedSteps; - private final Starter starter; - public StepSorter() { this.sortedSteps = new SortedSteps(); - this.starter = new Starter(); } + @Nonnull public String getSortedSteps(@Nonnull final List stepsInput) { + requireNonNull(stepsInput, "stepsInput"); final List steps = new ArrayList<>(stepsInput); final Step startingStep = getStartingStep(steps); @@ -24,25 +26,46 @@ public String getSortedSteps(@Nonnull final List stepsInput) { steps.remove(startingStep); final List stepsWithoutStart = new ArrayList<>(steps); - stepsWithoutStart.forEach(step -> { - final List availableSteps = getAvailableSteps(steps); - final List sortedAvailableSteps = new ArrayList<>(availableSteps); - sortedAvailableSteps.sort(Comparator.comparing(Step::getStepName)); - final Step nextStep = sortedAvailableSteps.get(0); - sortedSteps.addStep(nextStep); - steps.remove(nextStep); - }); + stepsWithoutStart.forEach(step -> addNextStepToResult(steps)); return sortedSteps.getStepsAsString(); } + + private void addNextStepToResult(@Nonnull final List steps){ + requireNonNull(steps, "steps"); + final List availableSteps = getAvailableSteps(steps); + final List sortedAvailableSteps = new ArrayList<>(availableSteps); + sortedAvailableSteps.sort(Comparator.comparing(Step::getStepName)); + final Step nextStep = sortedAvailableSteps.get(0); + sortedSteps.addStep(nextStep); + steps.remove(nextStep); + } + + @Nonnull + public List getStartingSteps(@Nonnull final List steps) { + requireNonNull(steps, "steps"); + final List startingSteps = new ArrayList<>(); + steps.forEach(step -> { + if (step.getDependsOn().isEmpty()) { + startingSteps.add(step); + } + }); + + return startingSteps; + } + + @Nonnull private Step getStartingStep(@Nonnull final List steps) { - final List startingSteps = starter.getStartingSteps(steps); + requireNonNull(steps, "steps"); + final List startingSteps = getStartingSteps(steps); startingSteps.sort(Comparator.comparing(Step::getStepName)); return startingSteps.get(0); } + @Nonnull private List getAvailableSteps(@Nonnull final List steps) { + requireNonNull(steps, "steps"); final List availableSteps = new ArrayList<>(); steps.forEach(step -> { diff --git a/src/test/java/org/haffson/adventofcode/days/day07/Day07Test.java b/src/test/java/org/haffson/adventofcode/days/day07/Day07Test.java index ae154e1..4b52b7e 100644 --- a/src/test/java/org/haffson/adventofcode/days/day07/Day07Test.java +++ b/src/test/java/org/haffson/adventofcode/days/day07/Day07Test.java @@ -5,10 +5,7 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -127,17 +124,6 @@ void setUp() { "Step K must be finished before step I can begin.", "Step J must be finished before step G can begin." )); - -// when(fileReaders.getInputList("src/main/resources/puzzle_input/day7_input.txt")) -// .thenReturn(List.of( -// "Step C must be finished before step A can begin.", -// "Step C must be finished before step F can begin.", -// "Step A must be finished before step B can begin.", -// "Step A must be finished before step D can begin.", -// "Step B must be finished before step E can begin.", -// "Step D must be finished before step E can begin.", -// "Step F must be finished before step E can begin." -// )); } @DisplayName("get the current AoC Day") @@ -152,7 +138,6 @@ void testGetDay() { @Test void test_firstPart_returnsExpectedResult() { //arrange -// final String expectedResult = "Part 1 - : " + "CABDFE"; final String expectedResult = "Part 1 - : " + "EPWCFXKISTZVJHDGNABLQYMORU"; //act @@ -161,105 +146,4 @@ void test_firstPart_returnsExpectedResult() { //assert assertThat(actualResult).isEqualTo(expectedResult); } - -// @Test -// void test_getInstructions(){ -// //arrange -// final FileReaders fileReaders = mock(FileReaders.class); -// -// when(fileReaders.getInputList("src/main/resources/puzzle_input/day7_input.txt")) -// .thenReturn(List.of( -// "Step C must be finished before step A can begin.", -// "Step C must be finished before step F can begin.", -// "Step A must be finished before step B can begin.", -// "Step A must be finished before step D can begin.", -// "Step B must be finished before step E can begin.", -// "Step D must be finished before step E can begin.", -// "Step F must be finished before step E can begin." -// )); -// -// final List expectedResult = List.of( -// new StepInstruction('C','A'), -// new StepInstruction('C','F'), -// new StepInstruction('A','B'), -// new StepInstruction('A','D'), -// new StepInstruction('B','E'), -// new StepInstruction('D','E'), -// new StepInstruction('F','E')); -// -// //act -// -// final List actualResult = day07.getInstructions() -// -// //assert -// assertThat() -// } - -// @Test -// void test_convertSteps(){ -// //arrange -// final List stepInstructions = List.of( -// new StepInstruction('C','A'), -// new StepInstruction('C','F'), -// new StepInstruction('A','B'), -// new StepInstruction('A','D'), -// new StepInstruction('B','E'), -// new StepInstruction('D','E'), -// new StepInstruction('F','E')); -// -// final List expectedResult = new ArrayList<>(); -// -// //act -// -// final List actualResult = day07.convertInstructionsToSteps(stepInstructions); -// //assert -// assertThat(actualResult).isEqualTo(expectedResult); -// } - - @Test - void test_convertSortedSteps(){ - //arrange - final List stepInstructions = List.of( - new StepInstruction('C','A'), - new StepInstruction('C','F'), - new StepInstruction('A','B'), - new StepInstruction('A','D'), - new StepInstruction('B','E'), - new StepInstruction('D','E'), - new StepInstruction('F','E')); - - final Map> expectedResult = Map.of('A',List.of('C'), - 'F',List.of('C'), - 'B',List.of('A'), - 'D',List.of('A'), - 'E',List.of('B','D','F'), - 'C',List.of()); - - - //act - - final Map> actualResult = day07.convertInstructionsToSortedSteps(stepInstructions); - //assert - assertThat(actualResult).isEqualTo(expectedResult); - } - -// @Test -// void test_convertMapToSteps(){ -// //arrange -// final Map> inputMap = Map.of('A',List.of('C'), -// 'F',List.of('C'), -// 'B',List.of('A'), -// 'D',List.of('A'), -// 'E',List.of('B','D','F'), -// 'C',List.of()); -// -// final List expectedResult = List.of(new Step()) -// -// //act -// -// final Map> actualResult = day07.convertInstructionsToSortedSteps(stepInstructions); -// //assert -// assertThat(actualResult).isEqualTo(expectedResult); -// } - } From cb5e0972dc2058b7667fe520e30672640c3d7200 Mon Sep 17 00:00:00 2001 From: PascalWo Date: Fri, 2 Sep 2022 11:19:44 +0200 Subject: [PATCH 16/19] Refactored more unnecessary code + transformed classes to records --- .../adventofcode/days/day07/Day07.java | 13 +- .../adventofcode/days/day07/SortedSteps.java | 20 +- .../haffson/adventofcode/days/day07/Step.java | 46 +--- .../days/day07/StepInstruction.java | 18 +- .../adventofcode/days/day07/StepSorter.java | 33 +-- .../adventofcode/days/day07/Day07Test.java | 202 +++++++++--------- .../days/day07/StepInstructionTest.java | 8 +- .../days/day07/StepSorterTest.java | 24 --- 8 files changed, 126 insertions(+), 238 deletions(-) diff --git a/src/main/java/org/haffson/adventofcode/days/day07/Day07.java b/src/main/java/org/haffson/adventofcode/days/day07/Day07.java index bc5d7f3..cbe2d57 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/Day07.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/Day07.java @@ -86,6 +86,7 @@ private long calculateSecondPart(@Nonnull final List inputStringList) { @Nonnull private List getSteps(@Nonnull final List instructions) { + requireNonNull(instructions, "instructions"); final Map> dependenciesByStep = convertInstructionsToSortedSteps(instructions); return Step.of(dependenciesByStep); } @@ -99,14 +100,14 @@ private Map> convertInstructionsToSortedSteps(@Nonnul final Map>> dependenciesByStep = new HashMap<>(); steps.forEach(step -> { - if (!dependenciesByStep.containsKey(step.getStepName())) { + if (!dependenciesByStep.containsKey(step.stepName())) { final List> dependencyList = new ArrayList<>(); - dependencyList.add(step.getDependsOn()); + dependencyList.add(step.dependsOn()); - dependenciesByStep.put(step.getStepName(), dependencyList); + dependenciesByStep.put(step.stepName(), dependencyList); } else { - dependenciesByStep.get(step.getStepName()).add(step.getDependsOn()); + dependenciesByStep.get(step.stepName()).add(step.dependsOn()); } }); @@ -121,8 +122,8 @@ private List convertInstructionsToSteps(@Nonnull final List completeSteps = new ArrayList<>(); stepInstructions.forEach(stepInstruction -> { - final Step step1 = new Step(stepInstruction.step(), new ArrayList<>()); - final Step step2 = new Step(stepInstruction.finishedBefore(), List.of(stepInstruction.step())); + final Step step1 = new Step(stepInstruction.previousStep(), new ArrayList<>()); + final Step step2 = new Step(stepInstruction.step(), List.of(stepInstruction.previousStep())); final List transformedSteps = List.of(step1, step2); completeSteps.addAll(transformedSteps); diff --git a/src/main/java/org/haffson/adventofcode/days/day07/SortedSteps.java b/src/main/java/org/haffson/adventofcode/days/day07/SortedSteps.java index 72f86c8..bce2475 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/SortedSteps.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/SortedSteps.java @@ -7,32 +7,22 @@ import static java.util.Objects.requireNonNull; -public class SortedSteps { - private final List stepSequence; - +public record SortedSteps(@Nonnull List stepSequence) { public SortedSteps() { - this.stepSequence = new ArrayList<>(); + this(new ArrayList<>()); } + @Nonnull public List getCharacterSequence() { final List characters = new ArrayList<>(); - stepSequence.forEach(step -> characters.add(step.getStepName())); + stepSequence.forEach(step -> characters.add(step.stepName())); return characters; } public void addStep(@Nonnull final Step nextStepToCheck) { requireNonNull(nextStepToCheck, "nextStepToCheck"); - if (isStepToCheckEmpty(nextStepToCheck)) { - return; - } - if (!stepSequence.contains(nextStepToCheck)) { - this.stepSequence.add(nextStepToCheck); - } - } - private boolean isStepToCheckEmpty(@Nonnull final Step stepToCheck) { - requireNonNull(stepToCheck, "stepToCheck"); - return stepToCheck.getStepName() == Character.MIN_VALUE; + this.stepSequence.add(nextStepToCheck); } @Nonnull diff --git a/src/main/java/org/haffson/adventofcode/days/day07/Step.java b/src/main/java/org/haffson/adventofcode/days/day07/Step.java index 54eef8d..58019f0 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/Step.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/Step.java @@ -4,58 +4,20 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.Objects; import static java.util.Objects.requireNonNull; -public final class Step { - private final char stepName; - - @Nonnull - private final List dependsOn; - - public Step(final char stepName, @Nonnull final List dependsOn) { - this.stepName = stepName; - this.dependsOn = requireNonNull(dependsOn, "dependsOn"); +public record Step(char stepName, @Nonnull List dependsOn) { + public Step { + requireNonNull(dependsOn, "dependsOn"); } public Step(final char stepName) { - this.stepName = stepName; - this.dependsOn = new ArrayList<>(); + this(stepName, new ArrayList<>()); } public static List of(@Nonnull final Map> dependenciesByStep) { requireNonNull(dependenciesByStep, "dependenciesByStep"); return dependenciesByStep.entrySet().stream().map(entry -> new Step(entry.getKey(), entry.getValue())).toList(); } - - public char getStepName() { - return stepName; - } - - @Nonnull - public List getDependsOn() { - return dependsOn; - } - - @Override - public boolean equals(final Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - final Step step = (Step) o; - return stepName == step.stepName && Objects.equals(dependsOn, step.dependsOn); - } - - @Override - public int hashCode() { - return Objects.hash(stepName, dependsOn); - } - - @Override - public String toString() { - return "Step{" + - "stepName=" + stepName + - ", dependsOn=" + dependsOn + - '}'; - } } diff --git a/src/main/java/org/haffson/adventofcode/days/day07/StepInstruction.java b/src/main/java/org/haffson/adventofcode/days/day07/StepInstruction.java index a442ba3..ea6d52b 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/StepInstruction.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/StepInstruction.java @@ -5,7 +5,7 @@ import static java.util.Objects.requireNonNull; -public record StepInstruction(char step, char finishedBefore) { +public record StepInstruction(char previousStep, char step) { @Nonnull public static StepInstruction of(@Nonnull final String input) { @@ -22,20 +22,4 @@ public static List of(@Nonnull final List inputList) { requireNonNull(inputList, "inputList"); return inputList.stream().map(StepInstruction::of).toList(); } - - @Override - public boolean equals(final Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - final StepInstruction that = (StepInstruction) o; - return step == that.step && finishedBefore == that.finishedBefore; - } - - @Override - public String toString() { - return "StepInstruction{" + - "step=" + step + - ", finishedBefore=" + finishedBefore + - '}'; - } } diff --git a/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java b/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java index 1b0046f..9940c9d 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java @@ -21,55 +21,30 @@ public String getSortedSteps(@Nonnull final List stepsInput) { requireNonNull(stepsInput, "stepsInput"); final List steps = new ArrayList<>(stepsInput); - final Step startingStep = getStartingStep(steps); - sortedSteps.addStep(startingStep); - steps.remove(startingStep); - final List stepsWithoutStart = new ArrayList<>(steps); - stepsWithoutStart.forEach(step -> addNextStepToResult(steps)); + stepsInput.forEach(step -> addNextStepToResult(steps)); return sortedSteps.getStepsAsString(); } - private void addNextStepToResult(@Nonnull final List steps){ + private void addNextStepToResult(@Nonnull final List steps) { requireNonNull(steps, "steps"); final List availableSteps = getAvailableSteps(steps); final List sortedAvailableSteps = new ArrayList<>(availableSteps); - sortedAvailableSteps.sort(Comparator.comparing(Step::getStepName)); + sortedAvailableSteps.sort(Comparator.comparing(Step::stepName)); final Step nextStep = sortedAvailableSteps.get(0); sortedSteps.addStep(nextStep); steps.remove(nextStep); } - @Nonnull - public List getStartingSteps(@Nonnull final List steps) { - requireNonNull(steps, "steps"); - final List startingSteps = new ArrayList<>(); - steps.forEach(step -> { - if (step.getDependsOn().isEmpty()) { - startingSteps.add(step); - } - }); - - return startingSteps; - } - - @Nonnull - private Step getStartingStep(@Nonnull final List steps) { - requireNonNull(steps, "steps"); - final List startingSteps = getStartingSteps(steps); - startingSteps.sort(Comparator.comparing(Step::getStepName)); - return startingSteps.get(0); - } - @Nonnull private List getAvailableSteps(@Nonnull final List steps) { requireNonNull(steps, "steps"); final List availableSteps = new ArrayList<>(); steps.forEach(step -> { - if (new HashSet<>(sortedSteps.getCharacterSequence()).containsAll(step.getDependsOn())) { + if (new HashSet<>(sortedSteps.getCharacterSequence()).containsAll(step.dependsOn())) { availableSteps.add(step); } }); diff --git a/src/test/java/org/haffson/adventofcode/days/day07/Day07Test.java b/src/test/java/org/haffson/adventofcode/days/day07/Day07Test.java index 4b52b7e..e9e1c39 100644 --- a/src/test/java/org/haffson/adventofcode/days/day07/Day07Test.java +++ b/src/test/java/org/haffson/adventofcode/days/day07/Day07Test.java @@ -22,107 +22,107 @@ void setUp() { when(fileReaders.getInputList("src/main/resources/puzzle_input/day7_input.txt")) .thenReturn(List.of( - "Step P must be finished before step Z can begin.", - "Step E must be finished before step O can begin.", - "Step X must be finished before step T can begin.", - "Step W must be finished before step V can begin.", - "Step K must be finished before step Y can begin.", - "Step C must be finished before step M can begin.", - "Step S must be finished before step R can begin.", - "Step T must be finished before step H can begin.", - "Step Z must be finished before step V can begin.", - "Step F must be finished before step L can begin.", - "Step V must be finished before step A can begin.", - "Step I must be finished before step A can begin.", - "Step J must be finished before step M can begin.", - "Step N must be finished before step Y can begin.", - "Step A must be finished before step B can begin.", - "Step H must be finished before step Q can begin.", - "Step Q must be finished before step O can begin.", - "Step D must be finished before step O can begin.", - "Step Y must be finished before step O can begin.", - "Step G must be finished before step L can begin.", - "Step B must be finished before step M can begin.", - "Step L must be finished before step U can begin.", - "Step M must be finished before step O can begin.", - "Step O must be finished before step U can begin.", - "Step R must be finished before step U can begin.", - "Step M must be finished before step U can begin.", - "Step Q must be finished before step U can begin.", - "Step K must be finished before step U can begin.", - "Step D must be finished before step R can begin.", - "Step A must be finished before step M can begin.", - "Step A must be finished before step Q can begin.", - "Step V must be finished before step Y can begin.", - "Step H must be finished before step G can begin.", - "Step P must be finished before step K can begin.", - "Step N must be finished before step A can begin.", - "Step P must be finished before step H can begin.", - "Step X must be finished before step Z can begin.", - "Step X must be finished before step K can begin.", - "Step Y must be finished before step U can begin.", - "Step F must be finished before step Q can begin.", - "Step W must be finished before step M can begin.", - "Step B must be finished before step L can begin.", - "Step E must be finished before step L can begin.", - "Step N must be finished before step O can begin.", - "Step I must be finished before step G can begin.", - "Step J must be finished before step H can begin.", - "Step Z must be finished before step N can begin.", - "Step V must be finished before step N can begin.", - "Step F must be finished before step B can begin.", - "Step A must be finished before step Y can begin.", - "Step Q must be finished before step R can begin.", - "Step L must be finished before step O can begin.", - "Step H must be finished before step U can begin.", - "Step V must be finished before step G can begin.", - "Step Z must be finished before step B can begin.", - "Step V must be finished before step J can begin.", - "Step V must be finished before step O can begin.", - "Step T must be finished before step D can begin.", - "Step Y must be finished before step M can begin.", - "Step B must be finished before step R can begin.", - "Step O must be finished before step R can begin.", - "Step C must be finished before step V can begin.", - "Step W must be finished before step T can begin.", - "Step P must be finished before step N can begin.", - "Step L must be finished before step R can begin.", - "Step V must be finished before step U can begin.", - "Step C must be finished before step J can begin.", - "Step N must be finished before step R can begin.", - "Step X must be finished before step S can begin.", - "Step X must be finished before step A can begin.", - "Step G must be finished before step O can begin.", - "Step A must be finished before step O can begin.", - "Step X must be finished before step O can begin.", - "Step D must be finished before step Y can begin.", - "Step C must be finished before step G can begin.", - "Step K must be finished before step D can begin.", - "Step N must be finished before step B can begin.", - "Step C must be finished before step B can begin.", - "Step W must be finished before step F can begin.", - "Step E must be finished before step Z can begin.", - "Step S must be finished before step V can begin.", - "Step G must be finished before step M can begin.", - "Step T must be finished before step B can begin.", - "Step W must be finished before step C can begin.", - "Step D must be finished before step G can begin.", - "Step L must be finished before step M can begin.", - "Step H must be finished before step D can begin.", - "Step G must be finished before step R can begin.", - "Step T must be finished before step J can begin.", - "Step A must be finished before step R can begin.", - "Step B must be finished before step O can begin.", - "Step J must be finished before step R can begin.", - "Step G must be finished before step U can begin.", - "Step K must be finished before step O can begin.", - "Step V must be finished before step L can begin.", - "Step M must be finished before step R can begin.", - "Step D must be finished before step U can begin.", - "Step H must be finished before step Y can begin.", - "Step P must be finished before step W can begin.", - "Step K must be finished before step I can begin.", - "Step J must be finished before step G can begin." + "Step P must be finished before previousStep Z can begin.", + "Step E must be finished before previousStep O can begin.", + "Step X must be finished before previousStep T can begin.", + "Step W must be finished before previousStep V can begin.", + "Step K must be finished before previousStep Y can begin.", + "Step C must be finished before previousStep M can begin.", + "Step S must be finished before previousStep R can begin.", + "Step T must be finished before previousStep H can begin.", + "Step Z must be finished before previousStep V can begin.", + "Step F must be finished before previousStep L can begin.", + "Step V must be finished before previousStep A can begin.", + "Step I must be finished before previousStep A can begin.", + "Step J must be finished before previousStep M can begin.", + "Step N must be finished before previousStep Y can begin.", + "Step A must be finished before previousStep B can begin.", + "Step H must be finished before previousStep Q can begin.", + "Step Q must be finished before previousStep O can begin.", + "Step D must be finished before previousStep O can begin.", + "Step Y must be finished before previousStep O can begin.", + "Step G must be finished before previousStep L can begin.", + "Step B must be finished before previousStep M can begin.", + "Step L must be finished before previousStep U can begin.", + "Step M must be finished before previousStep O can begin.", + "Step O must be finished before previousStep U can begin.", + "Step R must be finished before previousStep U can begin.", + "Step M must be finished before previousStep U can begin.", + "Step Q must be finished before previousStep U can begin.", + "Step K must be finished before previousStep U can begin.", + "Step D must be finished before previousStep R can begin.", + "Step A must be finished before previousStep M can begin.", + "Step A must be finished before previousStep Q can begin.", + "Step V must be finished before previousStep Y can begin.", + "Step H must be finished before previousStep G can begin.", + "Step P must be finished before previousStep K can begin.", + "Step N must be finished before previousStep A can begin.", + "Step P must be finished before previousStep H can begin.", + "Step X must be finished before previousStep Z can begin.", + "Step X must be finished before previousStep K can begin.", + "Step Y must be finished before previousStep U can begin.", + "Step F must be finished before previousStep Q can begin.", + "Step W must be finished before previousStep M can begin.", + "Step B must be finished before previousStep L can begin.", + "Step E must be finished before previousStep L can begin.", + "Step N must be finished before previousStep O can begin.", + "Step I must be finished before previousStep G can begin.", + "Step J must be finished before previousStep H can begin.", + "Step Z must be finished before previousStep N can begin.", + "Step V must be finished before previousStep N can begin.", + "Step F must be finished before previousStep B can begin.", + "Step A must be finished before previousStep Y can begin.", + "Step Q must be finished before previousStep R can begin.", + "Step L must be finished before previousStep O can begin.", + "Step H must be finished before previousStep U can begin.", + "Step V must be finished before previousStep G can begin.", + "Step Z must be finished before previousStep B can begin.", + "Step V must be finished before previousStep J can begin.", + "Step V must be finished before previousStep O can begin.", + "Step T must be finished before previousStep D can begin.", + "Step Y must be finished before previousStep M can begin.", + "Step B must be finished before previousStep R can begin.", + "Step O must be finished before previousStep R can begin.", + "Step C must be finished before previousStep V can begin.", + "Step W must be finished before previousStep T can begin.", + "Step P must be finished before previousStep N can begin.", + "Step L must be finished before previousStep R can begin.", + "Step V must be finished before previousStep U can begin.", + "Step C must be finished before previousStep J can begin.", + "Step N must be finished before previousStep R can begin.", + "Step X must be finished before previousStep S can begin.", + "Step X must be finished before previousStep A can begin.", + "Step G must be finished before previousStep O can begin.", + "Step A must be finished before previousStep O can begin.", + "Step X must be finished before previousStep O can begin.", + "Step D must be finished before previousStep Y can begin.", + "Step C must be finished before previousStep G can begin.", + "Step K must be finished before previousStep D can begin.", + "Step N must be finished before previousStep B can begin.", + "Step C must be finished before previousStep B can begin.", + "Step W must be finished before previousStep F can begin.", + "Step E must be finished before previousStep Z can begin.", + "Step S must be finished before previousStep V can begin.", + "Step G must be finished before previousStep M can begin.", + "Step T must be finished before previousStep B can begin.", + "Step W must be finished before previousStep C can begin.", + "Step D must be finished before previousStep G can begin.", + "Step L must be finished before previousStep M can begin.", + "Step H must be finished before previousStep D can begin.", + "Step G must be finished before previousStep R can begin.", + "Step T must be finished before previousStep J can begin.", + "Step A must be finished before previousStep R can begin.", + "Step B must be finished before previousStep O can begin.", + "Step J must be finished before previousStep R can begin.", + "Step G must be finished before previousStep U can begin.", + "Step K must be finished before previousStep O can begin.", + "Step V must be finished before previousStep L can begin.", + "Step M must be finished before previousStep R can begin.", + "Step D must be finished before previousStep U can begin.", + "Step H must be finished before previousStep Y can begin.", + "Step P must be finished before previousStep W can begin.", + "Step K must be finished before previousStep I can begin.", + "Step J must be finished before previousStep G can begin." )); } diff --git a/src/test/java/org/haffson/adventofcode/days/day07/StepInstructionTest.java b/src/test/java/org/haffson/adventofcode/days/day07/StepInstructionTest.java index c6fcabe..b0d8a8d 100644 --- a/src/test/java/org/haffson/adventofcode/days/day07/StepInstructionTest.java +++ b/src/test/java/org/haffson/adventofcode/days/day07/StepInstructionTest.java @@ -13,7 +13,7 @@ class StepInstructionTest { @Test void of_returnStepInstruction() { //arrange - final String input = "Step C must be finished before step A can begin."; + final String input = "Step C must be finished before previousStep A can begin."; final StepInstruction expectedResult = new StepInstruction('C', 'A'); //act final StepInstruction actualResult = StepInstruction.of(input); @@ -25,9 +25,9 @@ void of_returnStepInstruction() { @Test void of_returnStepInstructionList() { //arrange - final String input1 = "Step C must be finished before step A can begin."; - final String input2 = "Step C must be finished before step F can begin."; - final String input3 = "Step A must be finished before step B can begin."; + final String input1 = "Step C must be finished before previousStep A can begin."; + final String input2 = "Step C must be finished before previousStep F can begin."; + final String input3 = "Step A must be finished before previousStep B can begin."; final List inputList = List.of(input1, input2, input3); final List expectedResult = List.of(new StepInstruction('C', 'A'), diff --git a/src/test/java/org/haffson/adventofcode/days/day07/StepSorterTest.java b/src/test/java/org/haffson/adventofcode/days/day07/StepSorterTest.java index 6933ff9..425b64f 100644 --- a/src/test/java/org/haffson/adventofcode/days/day07/StepSorterTest.java +++ b/src/test/java/org/haffson/adventofcode/days/day07/StepSorterTest.java @@ -14,33 +14,9 @@ void setUp() { } -// @DisplayName("find starting step character") -// @Test -// void findStartingStep_shouldReturnStartingStep() { -// //arrange -// final List stepInstructions = List.of(new StepInstruction('C', 'A'), -// new StepInstruction('C', 'F'), -// new StepInstruction('A', 'B')); -// final StepSorter stepSorter = new StepSorter(stepInstructions); -// final List expectedResult = List.of('C'); -// //act -// stepSorter.findStartingStep(); -// final List actualResult = stepSorter.getStartingSteps(); -// //assert -// assertThat(actualResult).isEqualTo(expectedResult); -// } - @Test void getSortedSteps_shouldReturnSortedStepsAsString() { //arrange -// final List stepInstructions = List.of(new StepInstruction('C', 'A'), -// new StepInstruction('C', 'F'), -// new StepInstruction('A', 'B'), -// new StepInstruction('A', 'D'), -// new StepInstruction('B', 'E'), -// new StepInstruction('D', 'E'), -// new StepInstruction('F', 'E')); - final List steps = List.of(new Step('A', List.of('C')), new Step('F', List.of('C')), new Step('B', List.of('A')), From b2efe362d3b6a76d603dee68e5a801b981fa7f1c Mon Sep 17 00:00:00 2001 From: PascalWo Date: Fri, 2 Sep 2022 16:01:17 +0200 Subject: [PATCH 17/19] Refactored to remove complex map with List> --- .../adventofcode/days/day07/Day07.java | 71 ++-------------- .../adventofcode/days/day07/SortedSteps.java | 8 +- .../haffson/adventofcode/days/day07/Step.java | 6 -- .../days/day07/StepConverter.java | 85 +++++++++++++++++++ .../days/day07/StepInstruction.java | 8 +- .../adventofcode/days/day07/StepSorter.java | 7 +- .../adventofcode/days/day07/Day07Test.java | 19 +++++ .../adventofcode/days/day07/StepTest.java | 46 +++++----- 8 files changed, 148 insertions(+), 102 deletions(-) create mode 100644 src/main/java/org/haffson/adventofcode/days/day07/StepConverter.java diff --git a/src/main/java/org/haffson/adventofcode/days/day07/Day07.java b/src/main/java/org/haffson/adventofcode/days/day07/Day07.java index cbe2d57..661635b 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/Day07.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/Day07.java @@ -7,8 +7,6 @@ import org.springframework.stereotype.Component; import javax.annotation.Nonnull; -import java.util.ArrayList; -import java.util.HashMap; import java.util.List; import java.util.Map; @@ -73,75 +71,18 @@ public String secondPart() { */ @Nonnull private String calculateFirstPart(@Nonnull final List inputStringList) { - final List inputList = StepInstruction.of(inputStringList); - final List steps = getSteps(inputList); + requireNonNull(inputStringList, "inputStringList"); + + final StepConverter stepConverter = new StepConverter(); final StepSorter stepSorter = new StepSorter(); + final List inputList = StepInstruction.of(inputStringList); + final List steps = stepConverter.getSteps(inputList); + return stepSorter.getSortedSteps(steps); } private long calculateSecondPart(@Nonnull final List inputStringList) { return 0; } - - @Nonnull - private List getSteps(@Nonnull final List instructions) { - requireNonNull(instructions, "instructions"); - final Map> dependenciesByStep = convertInstructionsToSortedSteps(instructions); - return Step.of(dependenciesByStep); - } - - @Nonnull - private Map> convertInstructionsToSortedSteps(@Nonnull final List stepInstructions) { - requireNonNull(stepInstructions, "stepInstructions"); - - final List steps = convertInstructionsToSteps(stepInstructions); - - final Map>> dependenciesByStep = new HashMap<>(); - - steps.forEach(step -> { - if (!dependenciesByStep.containsKey(step.stepName())) { - final List> dependencyList = new ArrayList<>(); - - dependencyList.add(step.dependsOn()); - - dependenciesByStep.put(step.stepName(), dependencyList); - } else { - dependenciesByStep.get(step.stepName()).add(step.dependsOn()); - } - }); - - return duplicateFreeDependenciesByStep(dependenciesByStep); - } - - - @Nonnull - private List convertInstructionsToSteps(@Nonnull final List stepInstructions) { - requireNonNull(stepInstructions, "stepInstructions"); - - final List completeSteps = new ArrayList<>(); - - stepInstructions.forEach(stepInstruction -> { - final Step step1 = new Step(stepInstruction.previousStep(), new ArrayList<>()); - final Step step2 = new Step(stepInstruction.step(), List.of(stepInstruction.previousStep())); - - final List transformedSteps = List.of(step1, step2); - completeSteps.addAll(transformedSteps); - }); - - return completeSteps; - } - - @Nonnull - private Map> duplicateFreeDependenciesByStep( - @Nonnull final Map>> duplicatedDependenciesByStep) { - requireNonNull(duplicatedDependenciesByStep, "duplicatedDependenciesByStep"); - - final Map> dependenciesByStep = new HashMap<>(); - - duplicatedDependenciesByStep.forEach((stepName, stepDependencies) -> dependenciesByStep - .put(stepName, stepDependencies.stream().flatMap(List::stream).toList())); - - return dependenciesByStep; - } } diff --git a/src/main/java/org/haffson/adventofcode/days/day07/SortedSteps.java b/src/main/java/org/haffson/adventofcode/days/day07/SortedSteps.java index bce2475..14be420 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/SortedSteps.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/SortedSteps.java @@ -14,9 +14,10 @@ public SortedSteps() { @Nonnull public List getCharacterSequence() { - final List characters = new ArrayList<>(); - stepSequence.forEach(step -> characters.add(step.stepName())); - return characters; + final List characterSequence = new ArrayList<>(); + stepSequence.forEach(step -> characterSequence.add(step.stepName())); + + return characterSequence; } public void addStep(@Nonnull final Step nextStepToCheck) { @@ -28,6 +29,7 @@ public void addStep(@Nonnull final Step nextStepToCheck) { @Nonnull public String getStepsAsString() { final List characters = getCharacterSequence(); + return characters.stream().map(String::valueOf).collect(Collectors.joining()); } } diff --git a/src/main/java/org/haffson/adventofcode/days/day07/Step.java b/src/main/java/org/haffson/adventofcode/days/day07/Step.java index 58019f0..607f501 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/Step.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/Step.java @@ -3,7 +3,6 @@ import javax.annotation.Nonnull; import java.util.ArrayList; import java.util.List; -import java.util.Map; import static java.util.Objects.requireNonNull; @@ -15,9 +14,4 @@ public record Step(char stepName, @Nonnull List dependsOn) { public Step(final char stepName) { this(stepName, new ArrayList<>()); } - - public static List of(@Nonnull final Map> dependenciesByStep) { - requireNonNull(dependenciesByStep, "dependenciesByStep"); - return dependenciesByStep.entrySet().stream().map(entry -> new Step(entry.getKey(), entry.getValue())).toList(); - } } diff --git a/src/main/java/org/haffson/adventofcode/days/day07/StepConverter.java b/src/main/java/org/haffson/adventofcode/days/day07/StepConverter.java new file mode 100644 index 0000000..bfb6a26 --- /dev/null +++ b/src/main/java/org/haffson/adventofcode/days/day07/StepConverter.java @@ -0,0 +1,85 @@ +package org.haffson.adventofcode.days.day07; + +import javax.annotation.Nonnull; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.NoSuchElementException; + +import static java.util.Objects.requireNonNull; + +public class StepConverter { + + @Nonnull + public List getSteps(@Nonnull final List instructions) { + requireNonNull(instructions, "instructions"); + + final List steps = convertInstructionsToSteps(instructions); + + return joinSteps(steps); + } + + @Nonnull + private List convertInstructionsToSteps(@Nonnull final List instructions) { + requireNonNull(instructions, "instructions"); + + final List steps = new ArrayList<>(); + + instructions.forEach(instruction -> { + final Step step1 = new Step(instruction.step(), Collections.singletonList(instruction.previousStep())); + final Step step2 = new Step(instruction.previousStep()); + + steps.addAll(List.of(step1, step2)); + }); + + return steps; + } + + @Nonnull + private List joinSteps(@Nonnull final List duplicatedSteps) { + requireNonNull(duplicatedSteps, "duplicatedSteps"); + + final List joinedSteps = new ArrayList<>(); + + duplicatedSteps.forEach(stepToProve -> { + if (isStepAlreadyIncluded(joinedSteps, stepToProve)) { + final Step alreadyExistingStep = findDuplicateStep(joinedSteps, stepToProve); + final Step joinedStep = getStepWithJoinedDependencies(stepToProve, alreadyExistingStep); + + joinedSteps.remove(alreadyExistingStep); + joinedSteps.add(joinedStep); + } else { + joinedSteps.add(stepToProve); + } + }); + + return joinedSteps; + } + + private boolean isStepAlreadyIncluded(@Nonnull final List joinedSteps, @Nonnull final Step stepToProve) { + requireNonNull(joinedSteps, "joinedSteps"); + requireNonNull(stepToProve, "duplicatedStep"); + + return joinedSteps.stream().anyMatch(step -> step.stepName() == stepToProve.stepName()); + } + + @Nonnull + private Step findDuplicateStep(@Nonnull final List joinedSteps, @Nonnull final Step stepToProve) { + requireNonNull(joinedSteps, "steps"); + requireNonNull(stepToProve, "step"); + + return joinedSteps.stream().filter(duplicateStep -> stepToProve.stepName() == duplicateStep.stepName()).findFirst().orElseThrow(NoSuchElementException::new); + } + + @Nonnull + private Step getStepWithJoinedDependencies(@Nonnull final Step step1, @Nonnull final Step step2) { + requireNonNull(step1, "step1"); + requireNonNull(step2, "step2"); + + final List dependencies = new ArrayList<>(); + dependencies.addAll(step1.dependsOn()); + dependencies.addAll(step2.dependsOn()); + + return new Step(step1.stepName(), dependencies); + } +} diff --git a/src/main/java/org/haffson/adventofcode/days/day07/StepInstruction.java b/src/main/java/org/haffson/adventofcode/days/day07/StepInstruction.java index ea6d52b..6e4f8e0 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/StepInstruction.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/StepInstruction.java @@ -10,16 +10,18 @@ public record StepInstruction(char previousStep, char step) { @Nonnull public static StepInstruction of(@Nonnull final String input) { requireNonNull(input, "input"); + final String[] split1 = input.split(" "); - final char step = split1[1].charAt(0); - final char finishedBefore = split1[7].charAt(0); + final char previousStep = split1[1].charAt(0); + final char step = split1[7].charAt(0); - return new StepInstruction(step, finishedBefore); + return new StepInstruction(previousStep, step); } @Nonnull public static List of(@Nonnull final List inputList) { requireNonNull(inputList, "inputList"); + return inputList.stream().map(StepInstruction::of).toList(); } } diff --git a/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java b/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java index 9940c9d..82351b7 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java @@ -20,9 +20,9 @@ public StepSorter() { public String getSortedSteps(@Nonnull final List stepsInput) { requireNonNull(stepsInput, "stepsInput"); - final List steps = new ArrayList<>(stepsInput); + final List stepsCopy = new ArrayList<>(stepsInput); - stepsInput.forEach(step -> addNextStepToResult(steps)); + stepsInput.forEach(step -> addNextStepToResult(stepsCopy)); return sortedSteps.getStepsAsString(); } @@ -30,6 +30,7 @@ public String getSortedSteps(@Nonnull final List stepsInput) { private void addNextStepToResult(@Nonnull final List steps) { requireNonNull(steps, "steps"); + final List availableSteps = getAvailableSteps(steps); final List sortedAvailableSteps = new ArrayList<>(availableSteps); sortedAvailableSteps.sort(Comparator.comparing(Step::stepName)); @@ -41,6 +42,7 @@ private void addNextStepToResult(@Nonnull final List steps) { @Nonnull private List getAvailableSteps(@Nonnull final List steps) { requireNonNull(steps, "steps"); + final List availableSteps = new ArrayList<>(); steps.forEach(step -> { @@ -48,6 +50,7 @@ private List getAvailableSteps(@Nonnull final List steps) { availableSteps.add(step); } }); + return availableSteps; } } diff --git a/src/test/java/org/haffson/adventofcode/days/day07/Day07Test.java b/src/test/java/org/haffson/adventofcode/days/day07/Day07Test.java index e9e1c39..f0c525d 100644 --- a/src/test/java/org/haffson/adventofcode/days/day07/Day07Test.java +++ b/src/test/java/org/haffson/adventofcode/days/day07/Day07Test.java @@ -146,4 +146,23 @@ void test_firstPart_returnsExpectedResult() { //assert assertThat(actualResult).isEqualTo(expectedResult); } +// +// @Test +// void test_getSteps2(){ +// //arrange +// final List stepInstructions = List.of(new StepInstruction('C', 'A'), +// new StepInstruction('C', 'F'), +// new StepInstruction('A', 'B'), +// new StepInstruction('A', 'D'), +// new StepInstruction('B', 'E'), +// new StepInstruction('D', 'E'), +// new StepInstruction('F', 'E')); +// +// final List expectedResult = new ArrayList<>(); +// //actual +// +// final List actualResult = day07.getSteps(stepInstructions); +// //assert +// assertThat(actualResult).isEqualTo(expectedResult); +// } } diff --git a/src/test/java/org/haffson/adventofcode/days/day07/StepTest.java b/src/test/java/org/haffson/adventofcode/days/day07/StepTest.java index 4ca4953..34084d2 100644 --- a/src/test/java/org/haffson/adventofcode/days/day07/StepTest.java +++ b/src/test/java/org/haffson/adventofcode/days/day07/StepTest.java @@ -10,27 +10,27 @@ import static org.junit.jupiter.api.Assertions.*; class StepTest { - - @DisplayName("of() should return new List of Steps") - @Test - void of_returnListOfSteps() { - //arrange - final Map> inputMap = Map.of('A', List.of('C'), - 'F', List.of('C'), - 'B', List.of('A'), - 'D', List.of('A'), - 'E', List.of('B', 'D', 'F'), - 'C', List.of()); - - final List expectedResult = List.of(new Step('A', List.of('C')), - new Step('F', List.of('C')), - new Step('B', List.of('A')), - new Step('D', List.of('A')), - new Step('E', List.of('B', 'D', 'F')), - new Step('C')); - //act - final List actualResult = Step.of(inputMap); - //assert - assertThat(actualResult).usingRecursiveComparison().ignoringCollectionOrder().isEqualTo(expectedResult); - } +// +// @DisplayName("of() should return new List of Steps") +// @Test +// void of_returnListOfSteps() { +// //arrange +// final Map> inputMap = Map.of('A', List.of('C'), +// 'F', List.of('C'), +// 'B', List.of('A'), +// 'D', List.of('A'), +// 'E', List.of('B', 'D', 'F'), +// 'C', List.of()); +// +// final List expectedResult = List.of(new Step('A', List.of('C')), +// new Step('F', List.of('C')), +// new Step('B', List.of('A')), +// new Step('D', List.of('A')), +// new Step('E', List.of('B', 'D', 'F')), +// new Step('C')); +// //act +// final List actualResult = Step.of(inputMap); +// //assert +// assertThat(actualResult).usingRecursiveComparison().ignoringCollectionOrder().isEqualTo(expectedResult); +// } } From 26393a7f9d49d8fcecea412df38c54bb797bb3b3 Mon Sep 17 00:00:00 2001 From: PascalWo Date: Fri, 2 Sep 2022 16:38:52 +0200 Subject: [PATCH 18/19] added more test cases --- .../days/day07/SortedStepsTest.java | 69 +++++++++++++++++++ .../days/day07/StepConverterTest.java | 38 ++++++++++ .../days/day07/StepSorterTest.java | 10 +-- .../adventofcode/days/day07/StepTest.java | 36 ---------- 4 files changed, 110 insertions(+), 43 deletions(-) create mode 100644 src/test/java/org/haffson/adventofcode/days/day07/SortedStepsTest.java create mode 100644 src/test/java/org/haffson/adventofcode/days/day07/StepConverterTest.java delete mode 100644 src/test/java/org/haffson/adventofcode/days/day07/StepTest.java diff --git a/src/test/java/org/haffson/adventofcode/days/day07/SortedStepsTest.java b/src/test/java/org/haffson/adventofcode/days/day07/SortedStepsTest.java new file mode 100644 index 0000000..6fd70cf --- /dev/null +++ b/src/test/java/org/haffson/adventofcode/days/day07/SortedStepsTest.java @@ -0,0 +1,69 @@ +package org.haffson.adventofcode.days.day07; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +class SortedStepsTest { + + @DisplayName("Should return a char List of StepNames") + @Test + void getCharacterSequence() { + //arrange + final List steps = List.of(new Step('A', List.of('C')), + new Step('F', List.of('C')), + new Step('B', List.of('A')), + new Step('D', List.of('A')), + new Step('E', List.of('B', 'D', 'F')), + new Step('C')); + + final List expectedResult = List.of('A', 'F', 'B', 'D', 'E', 'C'); + + //actual + final SortedSteps sortedSteps = new SortedSteps(steps); + final List actualResult = sortedSteps.getCharacterSequence(); + + //assert + assertThat(actualResult).isEqualTo(expectedResult); + } + + @DisplayName("Should add Step to existing steps") + @Test + void addStep() { + //arrange + final Step existingStep = new Step('F', List.of('C')); + final Step step = new Step('A', List.of('C')); + + final SortedSteps expectedResult = new SortedSteps(List.of(existingStep, step)); + //actual + final SortedSteps actualResult = new SortedSteps(); + actualResult.addStep(existingStep); + actualResult.addStep(step); + + //assert + assertThat(actualResult).isEqualTo(expectedResult); + } + + @DisplayName("Should return a String of the SortedSteps") + @Test + void getStepsAsString() { + //arrange + final List steps = List.of(new Step('A', List.of('C')), + new Step('F', List.of('C')), + new Step('B', List.of('A')), + new Step('D', List.of('A')), + new Step('E', List.of('B', 'D', 'F')), + new Step('C')); + + final String expectedResult = "AFBDEC"; + //actual + final SortedSteps sortedSteps = new SortedSteps(steps); + final String actualResult = sortedSteps.getStepsAsString(); + + //assert + assertThat(actualResult).isEqualTo(expectedResult); + } +} diff --git a/src/test/java/org/haffson/adventofcode/days/day07/StepConverterTest.java b/src/test/java/org/haffson/adventofcode/days/day07/StepConverterTest.java new file mode 100644 index 0000000..545402b --- /dev/null +++ b/src/test/java/org/haffson/adventofcode/days/day07/StepConverterTest.java @@ -0,0 +1,38 @@ +package org.haffson.adventofcode.days.day07; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +class StepConverterTest { + + @DisplayName("Should return a List of steps when stepInstructions are given") + @Test + void getSteps() { + //arrange + final List stepInstructions = List.of(new StepInstruction('C', 'A'), + new StepInstruction('C', 'F'), + new StepInstruction('A', 'B'), + new StepInstruction('A', 'D'), + new StepInstruction('B', 'E'), + new StepInstruction('D', 'E'), + new StepInstruction('F', 'E')); + + final List expectedResult = List.of( + new Step('A', List.of('C')), + new Step('F', List.of('C')), + new Step('B', List.of('A')), + new Step('D', List.of('A')), + new Step('E', List.of('B', 'D', 'F')), + new Step('C')); + //actual + final StepConverter stepConverter = new StepConverter(); + final List actualResult = stepConverter.getSteps(stepInstructions); + + //assert + assertThat(actualResult).usingRecursiveComparison().ignoringCollectionOrder().isEqualTo(expectedResult); + } +} diff --git a/src/test/java/org/haffson/adventofcode/days/day07/StepSorterTest.java b/src/test/java/org/haffson/adventofcode/days/day07/StepSorterTest.java index 425b64f..0fb658b 100644 --- a/src/test/java/org/haffson/adventofcode/days/day07/StepSorterTest.java +++ b/src/test/java/org/haffson/adventofcode/days/day07/StepSorterTest.java @@ -1,6 +1,6 @@ package org.haffson.adventofcode.days.day07; -import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import java.util.List; @@ -9,11 +9,7 @@ class StepSorterTest { - @BeforeEach - void setUp() { - - } - + @DisplayName("Should return the steps in correct order") @Test void getSortedSteps_shouldReturnSortedStepsAsString() { //arrange @@ -28,8 +24,8 @@ void getSortedSteps_shouldReturnSortedStepsAsString() { final String expectedResult = "CABDFE"; //act - final String actualResult = stepSorter.getSortedSteps(steps); + //assert assertThat(actualResult).isEqualTo(expectedResult); } diff --git a/src/test/java/org/haffson/adventofcode/days/day07/StepTest.java b/src/test/java/org/haffson/adventofcode/days/day07/StepTest.java deleted file mode 100644 index 34084d2..0000000 --- a/src/test/java/org/haffson/adventofcode/days/day07/StepTest.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.haffson.adventofcode.days.day07; - -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -import java.util.List; -import java.util.Map; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.*; - -class StepTest { -// -// @DisplayName("of() should return new List of Steps") -// @Test -// void of_returnListOfSteps() { -// //arrange -// final Map> inputMap = Map.of('A', List.of('C'), -// 'F', List.of('C'), -// 'B', List.of('A'), -// 'D', List.of('A'), -// 'E', List.of('B', 'D', 'F'), -// 'C', List.of()); -// -// final List expectedResult = List.of(new Step('A', List.of('C')), -// new Step('F', List.of('C')), -// new Step('B', List.of('A')), -// new Step('D', List.of('A')), -// new Step('E', List.of('B', 'D', 'F')), -// new Step('C')); -// //act -// final List actualResult = Step.of(inputMap); -// //assert -// assertThat(actualResult).usingRecursiveComparison().ignoringCollectionOrder().isEqualTo(expectedResult); -// } -} From 223a2ea8ad419dc74cd0c59eca1db092cad99af8 Mon Sep 17 00:00:00 2001 From: PascalWo Date: Thu, 8 Sep 2022 11:24:07 +0200 Subject: [PATCH 19/19] Refactoring after code review --- .../adventofcode/days/day07/Day07.java | 2 +- .../adventofcode/days/day07/SortedSteps.java | 6 +-- .../haffson/adventofcode/days/day07/Step.java | 19 +++++-- .../days/day07/StepConverter.java | 51 ++++++------------- .../adventofcode/days/day07/StepSorter.java | 22 ++++---- .../adventofcode/days/day07/Day07Test.java | 19 ------- .../days/day07/SortedStepsTest.java | 29 ++++++----- .../days/day07/StepConverterTest.java | 11 ++-- .../days/day07/StepSorterTest.java | 21 +++++--- 9 files changed, 79 insertions(+), 101 deletions(-) diff --git a/src/main/java/org/haffson/adventofcode/days/day07/Day07.java b/src/main/java/org/haffson/adventofcode/days/day07/Day07.java index 661635b..c44134a 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/Day07.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/Day07.java @@ -79,7 +79,7 @@ private String calculateFirstPart(@Nonnull final List inputStringList) { final List inputList = StepInstruction.of(inputStringList); final List steps = stepConverter.getSteps(inputList); - return stepSorter.getSortedSteps(steps); + return stepSorter.getSortedSteps(steps).asString(); } private long calculateSecondPart(@Nonnull final List inputStringList) { diff --git a/src/main/java/org/haffson/adventofcode/days/day07/SortedSteps.java b/src/main/java/org/haffson/adventofcode/days/day07/SortedSteps.java index 14be420..d2b7cf6 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/SortedSteps.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/SortedSteps.java @@ -13,7 +13,7 @@ public SortedSteps() { } @Nonnull - public List getCharacterSequence() { + public List asCharacters() { final List characterSequence = new ArrayList<>(); stepSequence.forEach(step -> characterSequence.add(step.stepName())); @@ -27,8 +27,8 @@ public void addStep(@Nonnull final Step nextStepToCheck) { } @Nonnull - public String getStepsAsString() { - final List characters = getCharacterSequence(); + public String asString() { + final List characters = asCharacters(); return characters.stream().map(String::valueOf).collect(Collectors.joining()); } diff --git a/src/main/java/org/haffson/adventofcode/days/day07/Step.java b/src/main/java/org/haffson/adventofcode/days/day07/Step.java index 607f501..fe735b6 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/Step.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/Step.java @@ -1,17 +1,28 @@ package org.haffson.adventofcode.days.day07; import javax.annotation.Nonnull; -import java.util.ArrayList; -import java.util.List; +import java.util.HashSet; +import java.util.Set; import static java.util.Objects.requireNonNull; -public record Step(char stepName, @Nonnull List dependsOn) { +public record Step(char stepName, @Nonnull Set dependsOn) { public Step { requireNonNull(dependsOn, "dependsOn"); } public Step(final char stepName) { - this(stepName, new ArrayList<>()); + this(stepName, new HashSet<>()); + } + + @Nonnull + public Step mergeInDependenciesFrom(@Nonnull final Step stepToMerge) { + requireNonNull(stepToMerge, "stepToMerge"); + + final Set dependencies = new HashSet<>(); + dependencies.addAll(this.dependsOn()); + dependencies.addAll(stepToMerge.dependsOn()); + + return new Step(this.stepName, dependencies); } } diff --git a/src/main/java/org/haffson/adventofcode/days/day07/StepConverter.java b/src/main/java/org/haffson/adventofcode/days/day07/StepConverter.java index bfb6a26..c31cc39 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/StepConverter.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/StepConverter.java @@ -4,7 +4,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.NoSuchElementException; +import java.util.Optional; import static java.util.Objects.requireNonNull; @@ -26,7 +26,7 @@ private List convertInstructionsToSteps(@Nonnull final List steps = new ArrayList<>(); instructions.forEach(instruction -> { - final Step step1 = new Step(instruction.step(), Collections.singletonList(instruction.previousStep())); + final Step step1 = new Step(instruction.step(), Collections.singleton(instruction.previousStep())); final Step step2 = new Step(instruction.previousStep()); steps.addAll(List.of(step1, step2)); @@ -36,50 +36,31 @@ private List convertInstructionsToSteps(@Nonnull final List joinSteps(@Nonnull final List duplicatedSteps) { - requireNonNull(duplicatedSteps, "duplicatedSteps"); + private List joinSteps(@Nonnull final List stepsThatMayContainDuplicates) { + requireNonNull(stepsThatMayContainDuplicates, "stepsThatMayContainDuplicates"); final List joinedSteps = new ArrayList<>(); - duplicatedSteps.forEach(stepToProve -> { - if (isStepAlreadyIncluded(joinedSteps, stepToProve)) { - final Step alreadyExistingStep = findDuplicateStep(joinedSteps, stepToProve); - final Step joinedStep = getStepWithJoinedDependencies(stepToProve, alreadyExistingStep); - - joinedSteps.remove(alreadyExistingStep); - joinedSteps.add(joinedStep); - } else { - joinedSteps.add(stepToProve); - } + stepsThatMayContainDuplicates.forEach(stepToProve -> { + final Optional alreadyExistingStep = findDuplicateStep(joinedSteps, stepToProve); + alreadyExistingStep.ifPresentOrElse( + existingStep -> { + final Step joinedStep = stepToProve.mergeInDependenciesFrom(existingStep); + joinedSteps.remove(existingStep); + joinedSteps.add(joinedStep); + }, + () -> joinedSteps.add(stepToProve) + ); }); return joinedSteps; } - private boolean isStepAlreadyIncluded(@Nonnull final List joinedSteps, @Nonnull final Step stepToProve) { - requireNonNull(joinedSteps, "joinedSteps"); - requireNonNull(stepToProve, "duplicatedStep"); - - return joinedSteps.stream().anyMatch(step -> step.stepName() == stepToProve.stepName()); - } - @Nonnull - private Step findDuplicateStep(@Nonnull final List joinedSteps, @Nonnull final Step stepToProve) { + private Optional findDuplicateStep(@Nonnull final List joinedSteps, @Nonnull final Step stepToProve) { requireNonNull(joinedSteps, "steps"); requireNonNull(stepToProve, "step"); - return joinedSteps.stream().filter(duplicateStep -> stepToProve.stepName() == duplicateStep.stepName()).findFirst().orElseThrow(NoSuchElementException::new); - } - - @Nonnull - private Step getStepWithJoinedDependencies(@Nonnull final Step step1, @Nonnull final Step step2) { - requireNonNull(step1, "step1"); - requireNonNull(step2, "step2"); - - final List dependencies = new ArrayList<>(); - dependencies.addAll(step1.dependsOn()); - dependencies.addAll(step2.dependsOn()); - - return new Step(step1.stepName(), dependencies); + return joinedSteps.stream().filter(duplicateStep -> stepToProve.stepName() == duplicateStep.stepName()).findFirst(); } } diff --git a/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java b/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java index 82351b7..b188927 100644 --- a/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java +++ b/src/main/java/org/haffson/adventofcode/days/day07/StepSorter.java @@ -9,29 +9,25 @@ import static java.util.Objects.requireNonNull; public class StepSorter { - @Nonnull - private final SortedSteps sortedSteps; - - public StepSorter() { - this.sortedSteps = new SortedSteps(); - } @Nonnull - public String getSortedSteps(@Nonnull final List stepsInput) { + public SortedSteps getSortedSteps(@Nonnull final List stepsInput) { requireNonNull(stepsInput, "stepsInput"); + final SortedSteps sortedSteps = new SortedSteps(); + final List stepsCopy = new ArrayList<>(stepsInput); - stepsInput.forEach(step -> addNextStepToResult(stepsCopy)); + stepsInput.forEach(step -> addNextStepToResult(stepsCopy, sortedSteps)); - return sortedSteps.getStepsAsString(); + return sortedSteps; } - private void addNextStepToResult(@Nonnull final List steps) { + private void addNextStepToResult(@Nonnull final List steps, @Nonnull final SortedSteps sortedSteps) { requireNonNull(steps, "steps"); - final List availableSteps = getAvailableSteps(steps); + final List availableSteps = getAvailableSteps(steps, sortedSteps); final List sortedAvailableSteps = new ArrayList<>(availableSteps); sortedAvailableSteps.sort(Comparator.comparing(Step::stepName)); final Step nextStep = sortedAvailableSteps.get(0); @@ -40,13 +36,13 @@ private void addNextStepToResult(@Nonnull final List steps) { } @Nonnull - private List getAvailableSteps(@Nonnull final List steps) { + private List getAvailableSteps(@Nonnull final List steps, @Nonnull final SortedSteps sortedSteps) { requireNonNull(steps, "steps"); final List availableSteps = new ArrayList<>(); steps.forEach(step -> { - if (new HashSet<>(sortedSteps.getCharacterSequence()).containsAll(step.dependsOn())) { + if (new HashSet<>(sortedSteps.asCharacters()).containsAll(step.dependsOn())) { availableSteps.add(step); } }); diff --git a/src/test/java/org/haffson/adventofcode/days/day07/Day07Test.java b/src/test/java/org/haffson/adventofcode/days/day07/Day07Test.java index f0c525d..e9e1c39 100644 --- a/src/test/java/org/haffson/adventofcode/days/day07/Day07Test.java +++ b/src/test/java/org/haffson/adventofcode/days/day07/Day07Test.java @@ -146,23 +146,4 @@ void test_firstPart_returnsExpectedResult() { //assert assertThat(actualResult).isEqualTo(expectedResult); } -// -// @Test -// void test_getSteps2(){ -// //arrange -// final List stepInstructions = List.of(new StepInstruction('C', 'A'), -// new StepInstruction('C', 'F'), -// new StepInstruction('A', 'B'), -// new StepInstruction('A', 'D'), -// new StepInstruction('B', 'E'), -// new StepInstruction('D', 'E'), -// new StepInstruction('F', 'E')); -// -// final List expectedResult = new ArrayList<>(); -// //actual -// -// final List actualResult = day07.getSteps(stepInstructions); -// //assert -// assertThat(actualResult).isEqualTo(expectedResult); -// } } diff --git a/src/test/java/org/haffson/adventofcode/days/day07/SortedStepsTest.java b/src/test/java/org/haffson/adventofcode/days/day07/SortedStepsTest.java index 6fd70cf..80a9450 100644 --- a/src/test/java/org/haffson/adventofcode/days/day07/SortedStepsTest.java +++ b/src/test/java/org/haffson/adventofcode/days/day07/SortedStepsTest.java @@ -4,6 +4,7 @@ import org.junit.jupiter.api.Test; import java.util.List; +import java.util.Set; import static org.assertj.core.api.Assertions.assertThat; @@ -13,18 +14,18 @@ class SortedStepsTest { @Test void getCharacterSequence() { //arrange - final List steps = List.of(new Step('A', List.of('C')), - new Step('F', List.of('C')), - new Step('B', List.of('A')), - new Step('D', List.of('A')), - new Step('E', List.of('B', 'D', 'F')), + final List steps = List.of(new Step('A', Set.of('C')), + new Step('F', Set.of('C')), + new Step('B', Set.of('A')), + new Step('D', Set.of('A')), + new Step('E', Set.of('B', 'D', 'F')), new Step('C')); final List expectedResult = List.of('A', 'F', 'B', 'D', 'E', 'C'); //actual final SortedSteps sortedSteps = new SortedSteps(steps); - final List actualResult = sortedSteps.getCharacterSequence(); + final List actualResult = sortedSteps.asCharacters(); //assert assertThat(actualResult).isEqualTo(expectedResult); @@ -34,8 +35,8 @@ void getCharacterSequence() { @Test void addStep() { //arrange - final Step existingStep = new Step('F', List.of('C')); - final Step step = new Step('A', List.of('C')); + final Step existingStep = new Step('F', Set.of('C')); + final Step step = new Step('A', Set.of('C')); final SortedSteps expectedResult = new SortedSteps(List.of(existingStep, step)); //actual @@ -51,17 +52,17 @@ void addStep() { @Test void getStepsAsString() { //arrange - final List steps = List.of(new Step('A', List.of('C')), - new Step('F', List.of('C')), - new Step('B', List.of('A')), - new Step('D', List.of('A')), - new Step('E', List.of('B', 'D', 'F')), + final List steps = List.of(new Step('A', Set.of('C')), + new Step('F', Set.of('C')), + new Step('B', Set.of('A')), + new Step('D', Set.of('A')), + new Step('E', Set.of('B', 'D', 'F')), new Step('C')); final String expectedResult = "AFBDEC"; //actual final SortedSteps sortedSteps = new SortedSteps(steps); - final String actualResult = sortedSteps.getStepsAsString(); + final String actualResult = sortedSteps.asString(); //assert assertThat(actualResult).isEqualTo(expectedResult); diff --git a/src/test/java/org/haffson/adventofcode/days/day07/StepConverterTest.java b/src/test/java/org/haffson/adventofcode/days/day07/StepConverterTest.java index 545402b..c6fd0f3 100644 --- a/src/test/java/org/haffson/adventofcode/days/day07/StepConverterTest.java +++ b/src/test/java/org/haffson/adventofcode/days/day07/StepConverterTest.java @@ -4,6 +4,7 @@ import org.junit.jupiter.api.Test; import java.util.List; +import java.util.Set; import static org.assertj.core.api.Assertions.assertThat; @@ -22,11 +23,11 @@ void getSteps() { new StepInstruction('F', 'E')); final List expectedResult = List.of( - new Step('A', List.of('C')), - new Step('F', List.of('C')), - new Step('B', List.of('A')), - new Step('D', List.of('A')), - new Step('E', List.of('B', 'D', 'F')), + new Step('A', Set.of('C')), + new Step('F', Set.of('C')), + new Step('B', Set.of('A')), + new Step('D', Set.of('A')), + new Step('E', Set.of('B', 'D', 'F')), new Step('C')); //actual final StepConverter stepConverter = new StepConverter(); diff --git a/src/test/java/org/haffson/adventofcode/days/day07/StepSorterTest.java b/src/test/java/org/haffson/adventofcode/days/day07/StepSorterTest.java index 0fb658b..4fc3792 100644 --- a/src/test/java/org/haffson/adventofcode/days/day07/StepSorterTest.java +++ b/src/test/java/org/haffson/adventofcode/days/day07/StepSorterTest.java @@ -4,6 +4,7 @@ import org.junit.jupiter.api.Test; import java.util.List; +import java.util.Set; import static org.assertj.core.api.Assertions.assertThat; @@ -13,18 +14,24 @@ class StepSorterTest { @Test void getSortedSteps_shouldReturnSortedStepsAsString() { //arrange - final List steps = List.of(new Step('A', List.of('C')), - new Step('F', List.of('C')), - new Step('B', List.of('A')), - new Step('D', List.of('A')), - new Step('E', List.of('B', 'D', 'F')), + final List steps = List.of(new Step('A', Set.of('C')), + new Step('F', Set.of('C')), + new Step('B', Set.of('A')), + new Step('D', Set.of('A')), + new Step('E', Set.of('B', 'D', 'F')), new Step('C')); final StepSorter stepSorter = new StepSorter(); - final String expectedResult = "CABDFE"; + final SortedSteps expectedResult = new SortedSteps(); + expectedResult.addStep(new Step('C')); + expectedResult.addStep(new Step('A', Set.of('C'))); + expectedResult.addStep(new Step('B', Set.of('A'))); + expectedResult.addStep(new Step('D', Set.of('A'))); + expectedResult.addStep(new Step('F', Set.of('C'))); + expectedResult.addStep(new Step('E', Set.of('B', 'D', 'F'))); //act - final String actualResult = stepSorter.getSortedSteps(steps); + final SortedSteps actualResult = stepSorter.getSortedSteps(steps); //assert assertThat(actualResult).isEqualTo(expectedResult);