diff --git a/2022/README.md b/2022/README.md index a081fdf5cbca4d05ffbbeff11d10abb919d28fd1..5c62a28bbe635b67efc851268ab3a0c3e79b33b5 100644 --- a/2022/README.md +++ b/2022/README.md @@ -63,6 +63,23 @@ The subproblems are - *Aha!* one of the knapsacks in the sample data has 'L' as a common item, twice - Sum the priorities of all the "common items" +### Part 2 + +The subproblems are +- Determine an item's priority (solved from part 1) +- ~~Determine which items are present in exactly three knapsacks~~ + - ~~Determine which knapsacks each item is in~~ + - ~~I'm not sure that it matters, but what if a "triplet item" occurs multiple times in a knapsack; is it no longer a "triplet item"? We probably could check by finding out if an elf is in more than one triplet.~~ +- Looks like I misread the problem statement originally. It seems that we don't need to find the triplets; the triplets appear in order in the data, knapsacks {*i*, *i+1*, *i+2*} + - Assume the number of knapsacks is divisible by 3 + - Determine which item is common in each triplet + - Assume each triplet has exactly one "triplet item" +- Sum the priorities of all the "triplet items" + +### Refactoring opportunity + +Both problems involve finding a singular common character -- one among two strings, the other among three. + #Day 4 (coming soon) diff --git a/2022/src/main/java/edu/unl/cse/bohn/year2022/Day3.java b/2022/src/main/java/edu/unl/cse/bohn/year2022/Day3.java index 2e21cef5ccda4ba9174058b92b54e5e751967478..5cceef2e445845f0c09d35f38abdfcb322d2980e 100644 --- a/2022/src/main/java/edu/unl/cse/bohn/year2022/Day3.java +++ b/2022/src/main/java/edu/unl/cse/bohn/year2022/Day3.java @@ -2,8 +2,7 @@ package edu.unl.cse.bohn.year2022; import edu.unl.cse.bohn.Puzzle; -import java.util.Iterator; -import java.util.List; +import java.util.*; @SuppressWarnings("unused") public class Day3 extends Puzzle { @@ -37,51 +36,72 @@ public class Day3 extends Puzzle { @Override public long computePart2(List<String> data) { - return 0; + long prioritySum = 0; + if (data.size() % 3 != 0) { + throw new IllegalArgumentException("The number of knapsacks (" + data.size() + ") is not divisible by three."); + } + for (int i = 0; i < data.size(); i += 3) { + char commonItem = getCommonItem(data.get(i), data.get(i + 1), data.get(i + 2)); + prioritySum += getPriority(commonItem); + } + return prioritySum; } private char getCommonItem(String firstCompartment, String secondCompartment) { + return getCommonItem(firstCompartment, secondCompartment, null); + } + + private char getCommonItem(String firstCollection, String secondCollection, String thirdCollection) { Character commonItem = null; - List<Character> firstCompartmentItems = firstCompartment.chars().sorted().mapToObj(c -> (char) c).toList(); - List<Character> secondCompartmentItems = secondCompartment.chars().sorted().mapToObj(c -> (char) c).toList(); - Iterator<Character> firstCompartmentIterator = firstCompartmentItems.iterator(); - Iterator<Character> secondCompartmentIterator = secondCompartmentItems.iterator(); + List<Character> firstItems = firstCollection.chars().sorted().mapToObj(c -> (char) c).toList(); + List<Character> secondItems = secondCollection.chars().sorted().mapToObj(c -> (char) c).toList(); + List<Character> thirdItems = (thirdCollection == null) ? + List.copyOf(secondItems) : thirdCollection.chars().sorted().mapToObj(c -> (char) c).toList(); + Iterator<Character> firstIterator = firstItems.iterator(); + Iterator<Character> secondIterator = secondItems.iterator(); + Iterator<Character> thirdIterator = thirdItems.iterator(); Character firstItem = null; Character secondItem = null; - // with the items sorted, we will advance through the items until we reach the end one of the compartments - while (firstCompartmentIterator.hasNext() || secondCompartmentIterator.hasNext()) { - firstItem = (firstItem == null && firstCompartmentIterator.hasNext()) ? - firstCompartmentIterator.next() : firstItem; - secondItem = (secondItem == null && secondCompartmentIterator.hasNext()) ? - secondCompartmentIterator.next() : secondItem; - if (commonItem == null && (firstItem == null || secondItem == null)) { - throw new IllegalArgumentException("Reached the end of a compartment among " - + firstCompartment + " and " + secondCompartment + " without finding a common item."); - } - else if (firstItem == secondItem) { + Character thirdItem = null; + // with the items sorted, we will advance through the items until we reach the end of the compartments + while (firstIterator.hasNext() || secondIterator.hasNext() || thirdIterator.hasNext()) { + firstItem = (firstItem == null && firstIterator.hasNext()) ? + firstIterator.next() : firstItem; + secondItem = (secondItem == null && secondIterator.hasNext()) ? + secondIterator.next() : secondItem; + thirdItem = (thirdItem == null && thirdIterator.hasNext()) ? + thirdIterator.next() : thirdItem; + if (commonItem == null && (firstItem == null || secondItem == null || thirdItem == null)) { + throw new IllegalArgumentException("Reached the end of a compartment among {" + firstCollection + " " + + secondCollection + " " + thirdCollection + " without finding a common item."); + } else if (firstItem == secondItem && secondItem == thirdItem) { if (commonItem == null || commonItem == firstItem) { commonItem = firstItem; firstItem = null; secondItem = null; + thirdItem = null; } else { throw new IllegalStateException("Found a common item (" + firstItem + ") when one already exists " + - "(" + commonItem + ") for compartments " + firstCompartment + " and " + secondCompartment); + "(" + commonItem + ") among {" + firstCollection + " " + secondCollection + " " + + thirdCollection + "}"); } - } else if (firstItem != null && secondItem != null) { - if (firstItem < secondItem) { + } else if (firstItem != null && secondItem != null && thirdItem != null) { + if (firstItem < secondItem || firstItem < thirdItem) { firstItem = null; - } else { + } else if (secondItem < thirdItem) { secondItem = null; + } else { + thirdItem = null; } - } else { // if we've gotten this far with a null item, then we just need to exhaust the remaining string + } else { // if we've gotten this far with a null item, then we just need to exhaust the remaining strings firstItem = null; secondItem = null; + thirdItem = null; } } if (commonItem == null) { - throw new IllegalArgumentException("No common item found among " - + firstCompartment + " and " + secondCompartment); -// + firstCompartmentItems + " and " + secondCompartmentItems); + throw new IllegalArgumentException("No common item found among {" + + firstCollection + " " + secondCollection + " " + thirdCollection + "}"); } return commonItem; }