From 6841af359c29776de2b97c30b9f0cfa7f457acc1 Mon Sep 17 00:00:00 2001
From: Christopher Bohn <bohn@unl.edu>
Date: Wed, 15 Dec 2021 14:09:33 -0600
Subject: [PATCH] Day 13 complete
---
2021/README.md | 17 ++
.../java/edu/unl/cse/bohn/year2021/Day13.java | 150 ++++++++++++++++++
2 files changed, 167 insertions(+)
create mode 100644 2021/src/main/java/edu/unl/cse/bohn/year2021/Day13.java
diff --git a/2021/README.md b/2021/README.md
index 6669c6d..c31634c 100644
--- a/2021/README.md
+++ b/2021/README.md
@@ -148,3 +148,20 @@ for part 2, but we shall see...
Good news! I was wrong about needing to build the cave graph for part 2. I just
need to specialize my `Cave` inner class to change the rules for adding
children.
+
+# Day 13
+
+This looks straight-forward. No fancy data structures required. No clever
+re-framing the problem, either. Creating the "paper" requires a couple of steps
+but no big deal.
+
+Hmm... part 1 took longer than I think it should have. The big-O complexity is
+manageable, but I guess the constant factors are problematic.
+
+For part 2, I'm not even going to try to algorithmically determine which letters
+are created (and not just because I'd have to return soemthing other than a
+long integer).
+
+Hmm... part 2 really didn't take much longer than part 1 did, which suggests
+the computational pain point is in parsing the data and creating the "paper"
+and not in the folding.
diff --git a/2021/src/main/java/edu/unl/cse/bohn/year2021/Day13.java b/2021/src/main/java/edu/unl/cse/bohn/year2021/Day13.java
new file mode 100644
index 0000000..19a2497
--- /dev/null
+++ b/2021/src/main/java/edu/unl/cse/bohn/year2021/Day13.java
@@ -0,0 +1,150 @@
+package edu.unl.cse.bohn.year2021;
+
+import edu.unl.cse.bohn.Puzzle;
+
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+@SuppressWarnings("unused")
+public class Day13 extends Puzzle {
+ public record Point(int x, int y) {
+ public Point(String coordinates) {
+ this(Integer.parseInt(coordinates.split(",")[0]), Integer.parseInt(coordinates.split(",")[1]));
+ }
+ }
+
+ private List<String> folds;
+ private boolean[][] paper;
+
+ public Day13(boolean isProductionReady) {
+ super(isProductionReady);
+ sampleData = """
+ 6,10
+ 0,14
+ 9,10
+ 0,3
+ 10,4
+ 4,11
+ 6,0
+ 6,12
+ 4,1
+ 0,13
+ 10,12
+ 3,4
+ 3,0
+ 8,4
+ 1,10
+ 2,14
+ 8,10
+ 9,0
+
+ fold along y=7
+ fold along x=5""";
+ }
+
+ private void parseInput(List<String> data) {
+ int maximumX = Integer.MIN_VALUE, maximumY = Integer.MIN_VALUE;
+ Set<Point> points = new HashSet<>();
+ folds = new LinkedList<>();
+ int lineNumber = 0;
+ do {
+ Point point = new Point(data.get(lineNumber++));
+ points.add(point);
+ maximumX = Integer.max(maximumX, point.x());
+ maximumY = Integer.max(maximumY, point.y());
+ } while (!data.get(lineNumber).equals(""));
+ for (++lineNumber; lineNumber < data.size(); lineNumber++) {
+ String line = data.get(lineNumber);
+ folds.add(line.substring(line.lastIndexOf(' ') + 1));
+ }
+ paper = new boolean[maximumX + 1][maximumY + 1];
+ for (int i = 0; i < paper.length; i++) {
+ for (int j = 0; j < paper[i].length; j++) {
+ int x = i;
+ int y = j;
+ paper[x][y] = points.stream().anyMatch(point -> point.x() == x && point.y() == y);
+ }
+ }
+ }
+
+ @SuppressWarnings("DuplicatedCode")
+ private void foldPaper(String fold) {
+ int originalWidth = paper.length;
+ int originalHeight = paper[0].length;
+ char dimension = fold.charAt(0);
+ int seam = Integer.parseInt(fold.substring(2));
+ boolean[][] foldedPaper;
+ switch (dimension) {
+ case 'x' -> {
+ foldedPaper = new boolean[seam][originalHeight];
+ for (int x = 0; x < originalWidth; x++) {
+ for (int y = 0; y < originalHeight; y++) {
+ if (x < seam) {
+ foldedPaper[x][y] = paper[x][y];
+ } else if (x > seam) {
+ int mirrorX = seam - (x - seam);
+ foldedPaper[mirrorX][y] = foldedPaper[mirrorX][y] || paper[x][y];
+ }
+ }
+ }
+ }
+ case 'y' -> {
+ foldedPaper = new boolean[originalWidth][seam];
+ for (int x = 0; x < originalWidth; x++) {
+ for (int y = 0; y < originalHeight; y++) {
+ if (y < seam) {
+ foldedPaper[x][y] = paper[x][y];
+ } else if (y > seam) {
+ int mirrorY = seam - (y - seam);
+ foldedPaper[x][mirrorY] = foldedPaper[x][mirrorY] || paper[x][y];
+ }
+ }
+ }
+ }
+ default -> throw new IllegalArgumentException("Unexpected fold dimension: " + fold);
+ }
+ paper = foldedPaper;
+ }
+
+ private long countDots() {
+ long numberOfDots = 0;
+ for (boolean[] row : paper) {
+ for (boolean hasAPoint : row) {
+ if (hasAPoint) {
+ numberOfDots++;
+ }
+ }
+ }
+ return numberOfDots;
+ }
+
+ private void printDots() {
+ // transpose array
+ for (int j = 0; j < paper[0].length; j++) {
+ //noinspection ForLoopReplaceableByForEach
+ for (int i = 0; i < paper.length; i++) { // goodbye cache friendliness
+ System.out.print(paper[i][j] ? '#' : ' ');
+ }
+ System.out.println();
+ }
+ }
+
+ @Override
+ public long computePart1(List<String> data) {
+ parseInput(data);
+ foldPaper(folds.get(0));
+ return countDots();
+ }
+
+ @Override
+ public long computePart2(List<String> data) {
+ parseInput(data); // reset everything
+ for (String fold : folds) {
+ foldPaper(fold);
+ }
+ printDots();
+ return 0;
+ }
+}
--
GitLab