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;
}