From 187c435abf44d9617ce2ae8a91fe1effd1bd123f Mon Sep 17 00:00:00 2001
From: Christopher Bohn <bohn@unl.edu>
Date: Tue, 14 Dec 2021 19:52:17 -0600
Subject: [PATCH] Day 11 complete

---
 2021/README.md                                |  13 ++
 .../java/edu/unl/cse/bohn/year2021/Day11.java | 131 ++++++++++++++++++
 2 files changed, 144 insertions(+)
 create mode 100644 2021/src/main/java/edu/unl/cse/bohn/year2021/Day11.java

diff --git a/2021/README.md b/2021/README.md
index cd2668e..969c13e 100644
--- a/2021/README.md
+++ b/2021/README.md
@@ -121,3 +121,16 @@ This looks like a job for a stack!
 
 Update: Yes, yes it was a job for a stack. Some maps simplified matters but
 were not essential.
+
+## Day 11
+
+Part 1 looks straight-forward. As I did with Day 9, the nested array will have
+a "frame" to simplify checking neighbors. One point of clarification: if an
+octopus's energy reaches 11 due to neighbors' flashing, does it still reset to
+0, or does it *actually* flash at 10, reset to 0, and then takes on the energy
+from the other neighbor (*i.e.*, I should subtract 10 from 11, not blindly
+reset to 0). Or, upon rereading the spec, we don't reset to 0 until the very end
+of the step. Well, we'll find out...
+
+Part 2, isn't any more challenging than checking whether the number of flashes
+is equal to the number of octopi.
diff --git a/2021/src/main/java/edu/unl/cse/bohn/year2021/Day11.java b/2021/src/main/java/edu/unl/cse/bohn/year2021/Day11.java
new file mode 100644
index 0000000..cca4e94
--- /dev/null
+++ b/2021/src/main/java/edu/unl/cse/bohn/year2021/Day11.java
@@ -0,0 +1,131 @@
+package edu.unl.cse.bohn.year2021;
+
+import edu.unl.cse.bohn.Puzzle;
+
+import java.util.Arrays;
+import java.util.List;
+
+@SuppressWarnings("unused")
+public class Day11 extends Puzzle {
+    private int[][] octopi;
+
+    @SuppressWarnings("CommentedOutCode")
+    public Day11(boolean isProductionReady) {
+        super(isProductionReady);
+//        sampleData = """
+//                11111
+//                19991
+//                19191
+//                19991
+//                11111""";
+        sampleData = """
+                5483143223
+                2745854711
+                5264556173
+                6141336146
+                6357385478
+                4167524645
+                2176841721
+                6882881134
+                4846848554
+                5283751526""";
+    }
+
+    private void initializeOctopi(List<String> data) {
+        octopi = new int[data.size() + 2][data.get(0).length() + 2];
+        for (int[] row : octopi) {
+            Arrays.fill(row, Integer.MIN_VALUE);
+        }
+        for (int i = 0; i < data.size(); i++) {
+            String line = data.get(i);
+            for (int j = 0; j < line.length(); j++) {
+                octopi[i + 1][j + 1] = Integer.parseInt(String.valueOf(line.charAt(j)));
+            }
+        }
+    }
+
+    private void printOctopi() {
+        for (int i = 1; i < octopi.length; i++) {
+            for (int j = 1; j < octopi[i].length - 1; j++) {
+                if (octopi[i][j] < 0) {
+                    System.out.print("-");
+                } else {
+                    System.out.print(octopi[i][j]);
+                }
+            }
+            System.out.println();
+        }
+        System.out.println();
+    }
+
+    private long stepOctopi() {
+        boolean[][] hasFlashed = new boolean[octopi.length][octopi[0].length];
+        boolean stillFlashing = true;
+        for (boolean[] row : hasFlashed) {
+            Arrays.fill(row, false);
+        }
+        for (int i = 1; i < octopi.length-1; i++) {
+            for (int j = 1; j < octopi[i].length-1; j++) {
+                octopi[i][j]++;
+            }
+        }
+        while (stillFlashing) {
+            stillFlashing = false;
+            for (int i = 1; i < octopi.length - 1; i++) {
+                for (int j = 1; j < octopi[i].length - 1; j++) {
+                    if (octopi[i][j] > 9 && !hasFlashed[i][j]) {
+                        hasFlashed[i][j] = true;
+                        stillFlashing = true;
+                        octopi[i-1][j-1]++;
+                        octopi[i-1][j]++;
+                        octopi[i-1][j+1]++;
+                        octopi[i][j-1]++;
+                        octopi[i][j+1]++;
+                        octopi[i+1][j-1]++;
+                        octopi[i+1][j]++;
+                        octopi[i+1][j+1]++;
+                    }
+                }
+            }
+        }
+        long numberOfFlashes = 0;
+        for (int i = 0; i < octopi.length; i++) {
+            for (int j = 0; j < octopi[i].length; j++) {
+                if (octopi[i][j] < 0) {     // the frame
+                    octopi[i][j] = Integer.MIN_VALUE;
+                } else if (hasFlashed[i][j]) {
+                    octopi[i][j] = 0;
+                    numberOfFlashes++;
+                }
+            }
+        }
+        return numberOfFlashes;
+    }
+
+    @Override
+    public long computePart1(List<String> data) {
+//        maximumSteps = 2;
+        int maximumSteps = 100;
+        initializeOctopi(data);
+        long totalFlashes = 0;
+//        printOctopi();
+        for (int i = 0; i < maximumSteps; i++) {
+            totalFlashes += stepOctopi();
+//            printOctopi();
+        }
+        return totalFlashes;
+    }
+
+    @Override
+    public long computePart2(List<String> data) {
+        initializeOctopi(data);
+        long stepNumber = 0;
+        long numberOfOctopi = (long)data.size() * (long)data.get(0).length();
+        long numberOfFlashes;
+        do {
+            numberOfFlashes = stepOctopi();
+            stepNumber++;
+        } while (numberOfFlashes < numberOfOctopi);
+        return stepNumber;
+    }
+}
-- 
GitLab