From 88dc41c127b64abdfae8cc3a937df933d50a7bc1 Mon Sep 17 00:00:00 2001 From: Christopher Bohn <bohn@unl.edu> Date: Sat, 10 Dec 2022 16:10:44 -0600 Subject: [PATCH] Completed Year 2022 Day 10 --- 2022/README.md | 9 +++- .../java/edu/unl/cse/bohn/year2022/Day10.java | 20 ++++++-- .../year2022/computer/CathodeRayTube.java | 51 +++++++++++++++++++ .../cse/bohn/year2022/computer/Computer.java | 24 ++++----- 4 files changed, 87 insertions(+), 17 deletions(-) create mode 100644 2022/src/main/java/edu/unl/cse/bohn/year2022/computer/CathodeRayTube.java diff --git a/2022/README.md b/2022/README.md index ec0500e..6c537cf 100644 --- a/2022/README.md +++ b/2022/README.md @@ -322,7 +322,14 @@ That means that the clock cycle has advanced, but the accumulator hasn't updated ### Part 2 -... +- Determine whether to illuminate the pixel for the current clock cycle +- Determine the accumulator's value before the current instruction's result is latched in +- Determine whether that value falls within the sprite's range + +### Refactoring + +Recognizing that we're now looking at many things that happen before the results are latched-in at the end of the cycle, +I'm revisiting the signal strength code. ## Day 11 diff --git a/2022/src/main/java/edu/unl/cse/bohn/year2022/Day10.java b/2022/src/main/java/edu/unl/cse/bohn/year2022/Day10.java index 016e48d..773c986 100644 --- a/2022/src/main/java/edu/unl/cse/bohn/year2022/Day10.java +++ b/2022/src/main/java/edu/unl/cse/bohn/year2022/Day10.java @@ -1,6 +1,7 @@ package edu.unl.cse.bohn.year2022; import edu.unl.cse.bohn.Puzzle; +import edu.unl.cse.bohn.year2022.computer.CathodeRayTube; import edu.unl.cse.bohn.year2022.computer.Computer; import java.util.List; @@ -10,7 +11,10 @@ public class Day10 extends Puzzle { public static final int INITIAL_CYCLE_FOR_MEASUREMENT = 20; public static final int MEASUREMENT_STEP = 40; + public static final int SIZE_OF_DISPLAY = 240; + public static final int WIDTH_OF_DISPLAY = 40; + @SuppressWarnings("CommentedOutCode") public Day10(boolean isProductionReady) { super(isProductionReady); // sampleData = """ @@ -20,11 +24,9 @@ public class Day10 extends Puzzle { sampleData = muchLargerSampleData; } - private Computer computer = new Computer(); - @Override public long computePart1(List<String> data) { - computer = new Computer(); + Computer computer = new Computer(); computer.addInstructions(data); int sumOfSignalStrengths = 0; int i = 0; @@ -38,8 +40,18 @@ public class Day10 extends Puzzle { @Override public long computePart2(List<String> data) { - computer = new Computer(); + Computer computer = new Computer(); computer.addInstructions(data); + CathodeRayTube display = new CathodeRayTube(SIZE_OF_DISPLAY, WIDTH_OF_DISPLAY, 3); + boolean moreToDisplay = true; + int pixel = 0; + while (moreToDisplay) { + moreToDisplay = computer.advanceOneCycle(); + if (moreToDisplay) { + display.draw(computer.getAccumulatorDuringPreviousCycle()); + } + } + System.out.println(display); return 0; } diff --git a/2022/src/main/java/edu/unl/cse/bohn/year2022/computer/CathodeRayTube.java b/2022/src/main/java/edu/unl/cse/bohn/year2022/computer/CathodeRayTube.java new file mode 100644 index 0000000..915ba6c --- /dev/null +++ b/2022/src/main/java/edu/unl/cse/bohn/year2022/computer/CathodeRayTube.java @@ -0,0 +1,51 @@ +package edu.unl.cse.bohn.year2022.computer; + +import java.util.Arrays; + +public class CathodeRayTube { + private final Boolean[][] pixels; + private final int pixelsPerRow; + private final int spriteMargin; + private int row; + private int column; + + public CathodeRayTube(int numberOfPixels, int pixelsPerRow, int spriteWidth) { + this.pixelsPerRow = pixelsPerRow; + pixels = new Boolean[numberOfPixels / pixelsPerRow][pixelsPerRow]; + Arrays.stream(pixels).forEach(row -> Arrays.fill(row, null)); + this.spriteMargin = (spriteWidth - 1) / 2; + row = 0; + column = 0; + } + + @SuppressWarnings("UnusedReturnValue") + public boolean draw(int targetPixel) { + if (column == pixelsPerRow) { + row++; + column = 0; + if (row == pixels.length) { + row = 0; + } + } + pixels[row][column] = (Math.abs(targetPixel - column) <= spriteMargin); + boolean illuminated = pixels[row][column]; + column++; + return illuminated; + } + + @Override + public String toString() { + StringBuilder stringBuilder = new StringBuilder(pixels.length * (pixelsPerRow + 1)); + for (Boolean[] row : pixels) { + stringBuilder.append(System.lineSeparator()); + for (Boolean pixel : row) { + if (pixel == null) { + stringBuilder.append('?'); + } else { + stringBuilder.append(pixel ? '#' : ' '); + } + } + } + return stringBuilder.toString(); + } +} diff --git a/2022/src/main/java/edu/unl/cse/bohn/year2022/computer/Computer.java b/2022/src/main/java/edu/unl/cse/bohn/year2022/computer/Computer.java index 8477552..526d5c4 100644 --- a/2022/src/main/java/edu/unl/cse/bohn/year2022/computer/Computer.java +++ b/2022/src/main/java/edu/unl/cse/bohn/year2022/computer/Computer.java @@ -8,13 +8,13 @@ public class Computer { private final Context context; private final Deque<Instruction> instructions; private int reportedCycleNumber; - private int signalStrength; + private int accumulatorValueBeforeCurrentCycle; public Computer() { context = new Context(); instructions = new LinkedList<>(); reportedCycleNumber = 0; - signalStrength = 0; + accumulatorValueBeforeCurrentCycle = 0; } public void addInstruction(String instruction) { @@ -45,12 +45,12 @@ public class Computer { return reportedCycleNumber; } - private void setSignalStrengthForNextCycle() { - signalStrength = (getCycle() + 1) * context.rX; + public int getAccumulatorDuringPreviousCycle() { + return accumulatorValueBeforeCurrentCycle; } public int getSignalStrengthDuringPreviousCycle() { - return signalStrength; + return getAccumulatorDuringPreviousCycle() * getCycle(); } /** @@ -69,22 +69,22 @@ public class Computer { + reportedCycleNumber + " and the requested cycle is " + cycleNumber + "."); } while (!instructionsAreAvailable() && reportedCycleNumber < cycleNumber) { + accumulatorValueBeforeCurrentCycle = context.rX; if (context.clockCycle + instructions.getFirst().getDuration() > cycleNumber) { - // if executing the next instruction would advance the clock too far - reportedCycleNumber = cycleNumber - 1; - setSignalStrengthForNextCycle(); - reportedCycleNumber++; + reportedCycleNumber = cycleNumber; } else { Instruction nextInstruction = instructions.removeFirst(); - reportedCycleNumber = context.clockCycle + nextInstruction.getDuration() - 1; - setSignalStrengthForNextCycle(); nextInstruction.execute(context); - reportedCycleNumber++; + reportedCycleNumber = context.clockCycle; } } return reportedCycleNumber == cycleNumber; } + public boolean advanceOneCycle() { + return advanceToCycle(getCycle() + 1); + } + public String toString() { return "reported cycle: " + getCycle() + " (actual " + context.clockCycle + ")" + "\tRX: " + context.rX + "\t" + (instructionsAreAvailable() ? "--idle--" : (context.clockCycle == getCycle() ? " next" : "current") -- GitLab