From 2610bc51c06506345305f19b3a1f76eb6289be7d Mon Sep 17 00:00:00 2001
From: Christopher Bohn <bohn@unl.edu>
Date: Sun, 12 Dec 2021 19:18:47 -0600
Subject: [PATCH] Day 6 complete

---
 2021/README.md                                |  9 +++-
 .../main/java/edu/unl/cse/bohn/Puzzle.java    |  4 +-
 .../java/edu/unl/cse/bohn/year2021/Day1.java  |  4 +-
 .../java/edu/unl/cse/bohn/year2021/Day2.java  | 10 ++--
 .../java/edu/unl/cse/bohn/year2021/Day3.java  | 28 +++++-----
 .../java/edu/unl/cse/bohn/year2021/Day4.java  |  4 +-
 .../java/edu/unl/cse/bohn/year2021/Day5.java  |  4 +-
 .../java/edu/unl/cse/bohn/year2021/Day6.java  | 53 +++++++++++++++++++
 8 files changed, 88 insertions(+), 28 deletions(-)
 create mode 100644 2021/src/main/java/edu/unl/cse/bohn/year2021/Day6.java

diff --git a/2021/README.md b/2021/README.md
index 7290326..4d512b0 100644
--- a/2021/README.md
+++ b/2021/README.md
@@ -35,4 +35,11 @@ less-complex approaches. The straight-forward design I came up with for Day 5 is
 O(num_lines * num_rows * num_columns); the algebraic approach would be 
 O(num_lines^2), so not too much of a big deal on this problem. But (I'm sure)
 there will be some problems whose straight-forward solution are a tad 
-intractable. 
\ No newline at end of file
+intractable.
+
+## Day 6
+
+For example, in the problem statement practically *screams* that the
+obvious solution grows exponentially. Normally, death would keep the population
+under control, but I guess Death Takes a Holiday. One little extra gotcha:
+26984457539 > Integer.MAX_INT, so I need to use a long integer.
\ No newline at end of file
diff --git a/2021/src/main/java/edu/unl/cse/bohn/Puzzle.java b/2021/src/main/java/edu/unl/cse/bohn/Puzzle.java
index b8e5910..100704c 100644
--- a/2021/src/main/java/edu/unl/cse/bohn/Puzzle.java
+++ b/2021/src/main/java/edu/unl/cse/bohn/Puzzle.java
@@ -11,8 +11,8 @@ public abstract class Puzzle {
         this.isProductionReady = isProductionReady;
     }
 
-    public abstract int computePart1(List<String> data);
-    public abstract int computePart2(List<String> data);
+    public abstract long computePart1(List<String> data);
+    public abstract long computePart2(List<String> data);
 
     public void solvePuzzle(ImportData dataSource) {
         List<String> data = null;
diff --git a/2021/src/main/java/edu/unl/cse/bohn/year2021/Day1.java b/2021/src/main/java/edu/unl/cse/bohn/year2021/Day1.java
index e1b1be5..3c938d5 100644
--- a/2021/src/main/java/edu/unl/cse/bohn/year2021/Day1.java
+++ b/2021/src/main/java/edu/unl/cse/bohn/year2021/Day1.java
@@ -37,13 +37,13 @@ public class Day1 extends Puzzle {
     }
 
     @Override
-    public int computePart1(List<String> data) {
+    public long computePart1(List<String> data) {
         depths = data.stream().map(Integer::parseInt).toList();
         return countIncreases(depths);
     }
 
     @Override
-    public int computePart2(List<String> data) {
+    public long computePart2(List<String> data) {
         int numberOfWindows = depths.size() - 2;
         List<Integer> slidingWindows = new ArrayList<>(numberOfWindows);
         for (int i = 0; i < numberOfWindows; i++) {
diff --git a/2021/src/main/java/edu/unl/cse/bohn/year2021/Day2.java b/2021/src/main/java/edu/unl/cse/bohn/year2021/Day2.java
index 92585ee..b837c6d 100644
--- a/2021/src/main/java/edu/unl/cse/bohn/year2021/Day2.java
+++ b/2021/src/main/java/edu/unl/cse/bohn/year2021/Day2.java
@@ -11,10 +11,10 @@ public class Day2 extends Puzzle {
 
     private List<NavigationInstruction> navigationInstructions;
 
-    private int range;
-    private int depth;
+    private long range;
+    private long depth;
     @SuppressWarnings("FieldCanBeLocal")
-    private int aim;
+    private long aim;
 
     public Day2(boolean isProductionReady) {
         super(isProductionReady);
@@ -28,7 +28,7 @@ public class Day2 extends Puzzle {
     }
 
     @Override
-    public int computePart1(List<String> data) {
+    public long computePart1(List<String> data) {
         navigationInstructions = data.stream()
                 .map(instruction -> new NavigationInstruction(
                         instruction.split(" ")[0],
@@ -48,7 +48,7 @@ public class Day2 extends Puzzle {
     }
 
     @Override
-    public int computePart2(List<String> data) {
+    public long computePart2(List<String> data) {
         range = 0;
         depth = 0;
         aim = 0;
diff --git a/2021/src/main/java/edu/unl/cse/bohn/year2021/Day3.java b/2021/src/main/java/edu/unl/cse/bohn/year2021/Day3.java
index fa94aab..7f30d2e 100644
--- a/2021/src/main/java/edu/unl/cse/bohn/year2021/Day3.java
+++ b/2021/src/main/java/edu/unl/cse/bohn/year2021/Day3.java
@@ -8,7 +8,7 @@ import java.util.function.BiPredicate;
 
 @SuppressWarnings("unused")
 public class Day3 extends Puzzle {
-    private List<Integer> diagnosticReports;
+    private List<Long> diagnosticReports;
     private int reportLength;
     private int[] ones, zeroes;
 
@@ -30,8 +30,8 @@ public class Day3 extends Puzzle {
     }
 
     @Override
-    public int computePart1(List<String> data) {
-        diagnosticReports = data.stream().map(report -> Integer.parseInt(report, 2)).toList();
+    public long computePart1(List<String> data) {
+        diagnosticReports = data.stream().map(report -> Long.parseLong(report, 2)).toList();
         reportLength = data.get(0).length();
         ones = new int[]{
                 0, 0, 0, 0, 0, 0, 0, 0,
@@ -43,17 +43,17 @@ public class Day3 extends Puzzle {
                 0, 0, 0, 0, 0, 0, 0, 0,
                 0, 0, 0, 0, 0, 0, 0, 0,
                 0, 0, 0, 0, 0, 0, 0, 0};
-        for (int report : diagnosticReports) {
+        for (long report : diagnosticReports) {
             for (int bit = 0; bit < reportLength; bit++) {
-                if ((report & (1 << bit)) == 0) {
+                if ((report & 1L << bit) == 0) {
                     zeroes[bit]++;
                 } else {
                     ones[bit]++;
                 }
             }
         }
-        int gamma = 0;
-        int epsilon = 0;
+        long gamma = 0;
+        long epsilon = 0;
         for (int bit = 0; bit < reportLength; bit++) {
             if (ones[bit] > zeroes[bit]) {
                 gamma |= (1 << bit);
@@ -64,8 +64,8 @@ public class Day3 extends Puzzle {
         return gamma * epsilon;
     }
 
-    private Integer filterReports(int[] onesArray, int[] zeroesArray, BiPredicate<Integer, Integer> predicate) {
-        List<Integer> workingSet = new ArrayList<>(diagnosticReports);
+    private Long filterReports(int[] onesArray, int[] zeroesArray, BiPredicate<Integer, Integer> predicate) {
+        List<Long> workingSet = new ArrayList<>(diagnosticReports);
         int bit = reportLength - 1;
         int numberOfOnes = onesArray[bit];
         int numberOfZeroes = zeroesArray[bit];
@@ -84,8 +84,8 @@ public class Day3 extends Puzzle {
             // Need to re-count the ones and zeroes since the old counts are now wrong
             if (bit >= 0) {
                 numberOfOnes = numberOfZeroes = 0;
-                for (int report : workingSet) {
-                    if ((report & (1 << bit)) == 0) {
+                for (long report : workingSet) {
+                    if ((report & (1L << bit)) == 0) {
                         numberOfZeroes++;
                     } else {
                         numberOfOnes++;
@@ -97,10 +97,10 @@ public class Day3 extends Puzzle {
     }
 
     @Override
-    public int computePart2(List<String> data) {
-        Integer oxygenGeneratorRating = filterReports(ones, zeroes,
+    public long computePart2(List<String> data) {
+        Long oxygenGeneratorRating = filterReports(ones, zeroes,
                 (numberOfOnes, numberOfZeroes) -> numberOfOnes >= numberOfZeroes);
-        Integer co2ScrubberRating = filterReports(ones, zeroes,
+        Long co2ScrubberRating = filterReports(ones, zeroes,
                 (numberOfOnes, numberOfZeroes) -> numberOfOnes < numberOfZeroes);
         return oxygenGeneratorRating * co2ScrubberRating;
     }
diff --git a/2021/src/main/java/edu/unl/cse/bohn/year2021/Day4.java b/2021/src/main/java/edu/unl/cse/bohn/year2021/Day4.java
index 46fa1c2..ead3f3b 100644
--- a/2021/src/main/java/edu/unl/cse/bohn/year2021/Day4.java
+++ b/2021/src/main/java/edu/unl/cse/bohn/year2021/Day4.java
@@ -71,7 +71,7 @@ public class Day4 extends Puzzle {
     }
 
     @Override
-    public int computePart1(List<String> data) {
+    public long computePart1(List<String> data) {
         parseData(data);
         Iterator<Integer> numberIterator = numbers.iterator();
         while (cards.stream().noneMatch(BingoCard::hasBingo) && numberIterator.hasNext()) {
@@ -85,7 +85,7 @@ public class Day4 extends Puzzle {
     }
 
     @Override
-    public int computePart2(List<String> data) {
+    public long computePart2(List<String> data) {
         Iterator<Integer> numberIterator = numbers.iterator();
         while ((cards.stream().filter(BingoCard::hasBingo).count() < cards.size() - 1) && numberIterator.hasNext()) {
             int number = numberIterator.next();
diff --git a/2021/src/main/java/edu/unl/cse/bohn/year2021/Day5.java b/2021/src/main/java/edu/unl/cse/bohn/year2021/Day5.java
index 21a443d..cd63deb 100644
--- a/2021/src/main/java/edu/unl/cse/bohn/year2021/Day5.java
+++ b/2021/src/main/java/edu/unl/cse/bohn/year2021/Day5.java
@@ -95,13 +95,13 @@ public class Day5 extends Puzzle {
     }
 
     @Override
-    public int computePart1(List<String> data) {
+    public long computePart1(List<String> data) {
         parseData(data, false);
         return countIntersectingVentLines();
     }
 
     @Override
-    public int computePart2(List<String> data) {
+    public long computePart2(List<String> data) {
         parseData(data, true);
         return countIntersectingVentLines();
     }
diff --git a/2021/src/main/java/edu/unl/cse/bohn/year2021/Day6.java b/2021/src/main/java/edu/unl/cse/bohn/year2021/Day6.java
new file mode 100644
index 0000000..703f344
--- /dev/null
+++ b/2021/src/main/java/edu/unl/cse/bohn/year2021/Day6.java
@@ -0,0 +1,53 @@
+package edu.unl.cse.bohn.year2021;
+
+import edu.unl.cse.bohn.Puzzle;
+
+import java.util.Arrays;
+import java.util.List;
+
+@SuppressWarnings("unused")
+public class Day6 extends Puzzle {
+    private long[] numberOfFishAtCounter;
+
+    public Day6(boolean isProductionReady) {
+        super(isProductionReady);
+        sampleData = "3,4,3,1,2";
+    }
+
+    private void initializeFishCounters(List<String> data) {
+        List<Integer> fishCounters = Arrays.stream(data.get(0).split(","))
+                .mapToInt(Integer::parseInt)
+                .boxed().toList();
+        numberOfFishAtCounter = new long[9];
+        Arrays.fill(numberOfFishAtCounter, 0);
+        for (int fish : fishCounters) {
+            numberOfFishAtCounter[fish]++;
+        }
+    }
+
+    private void spawnFish(int numberOfDays) {
+        for (int day = 0; day < numberOfDays; day++) {
+            long spawningFish = numberOfFishAtCounter[0];
+            //noinspection ManualArrayCopy
+            for(int counter = 0; counter < 8; counter++) {
+                numberOfFishAtCounter[counter] = numberOfFishAtCounter[counter+1];
+            }
+            numberOfFishAtCounter[8] = spawningFish;    // new fish
+            numberOfFishAtCounter[6] += spawningFish;   // reset fish
+        }
+    }
+
+    @Override
+    public long computePart1(List<String> data) {
+        initializeFishCounters(data);
+        spawnFish(80);
+        return Arrays.stream(numberOfFishAtCounter).reduce(Long::sum).orElseThrow();
+    }
+
+    @Override
+    public long computePart2(List<String> data) {
+        initializeFishCounters(data);
+        spawnFish(256);
+        return Arrays.stream(numberOfFishAtCounter).reduce(Long::sum).orElseThrow();
+    }
+}
-- 
GitLab