diff --git a/2022/README.md b/2022/README.md index 808f8f35329a00548061c885ebb79fd325865642..2398981145cea24518a7a15f1119aecb6d200520 100644 --- a/2022/README.md +++ b/2022/README.md @@ -51,7 +51,7 @@ Seems pretty straight-forward. ### Refactoring opportunity Parts 1 & 2 differ in whether we determine the outcome based off of "my" hand, or whether we determine "my" hand based -o ff of the outcome. +off of the outcome. Where we parameterized the commonality on Day 1, today we'll simply extract the commonality into a helper method. ## Day 3 @@ -119,5 +119,40 @@ No, the thing to do is to extract the common part out into a helper method. ## Day 5 +- [The problem](https://adventofcode.com/2022/day/5) +- [The solution](src/main/java/edu/unl/cse/bohn/year2022/Day5.java) + +We've hit the first puzzle whose input will require a little creativity when parsing. + +### Part 1 + +The subproblems are +- Separate the initial conditions from the subsequent instructions + - Assume there is exactly one blank line between them +- Represent the stacks + - At the risk of diving into the solution space, *obviously* we'll do this with a list of stacks + - Determine how many stacks there are + - Assume that the last line of the initial conditions is the stack numbers, beginning with ' ' followed by a '1' + - Assume the stack numbers are in-order (*i.e.*, the last index tells us how many there are) + - Can we assume there are only a single-digit number of stacks? + - Assume all crates are of the form "[?]" + - Part of that is an assumption that a crate can be represented with a single character -- and I'm going to further + assume it's not ' ' + - Assume an empty space atop a stack is of the form " " + - Assume exactly one space between stacks +- Follow the instructions + - The regular format of the instructions will make them easy to parse + - (Solution space) pop/push will be easy +- Output the top of each stack, in order + +Why do I have the feeling that there'll be some version of +[The Towers of Hanoi](https://en.wikipedia.org/wiki/Tower_of_Hanoi) before we're done? + +### Part 2 + +### Refactoring opportunity + +## Day 6 + (coming soon) diff --git a/2022/src/main/java/edu/unl/cse/bohn/year2022/Day5.java b/2022/src/main/java/edu/unl/cse/bohn/year2022/Day5.java new file mode 100644 index 0000000000000000000000000000000000000000..dfa5b323da06bd2d413062861fae78c2fae76f61 --- /dev/null +++ b/2022/src/main/java/edu/unl/cse/bohn/year2022/Day5.java @@ -0,0 +1,95 @@ +package edu.unl.cse.bohn.year2022; + +import edu.unl.cse.bohn.Puzzle; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Stack; + +@SuppressWarnings("unused") +public class Day5 extends Puzzle { + public Day5(boolean isProductionReady) { + super(isProductionReady); + //noinspection EscapedSpace + sampleData = """ + \s [D] \s + [N] [C] \s + [Z] [M] [P] + 1 2 3\s + + move 1 from 2 to 1 + move 3 from 1 to 3 + move 2 from 2 to 1 + move 1 from 1 to 2"""; + } + + @Override + public long computePart1(List<String> data) { + List<Stack<Character>> stacks = createStacks(data); + rearrangeCrates(stacks, data); + String topsOfStacks = getTopsOfStacks(stacks); + System.out.println("Crates at the top of the stacks: " + topsOfStacks); + return 0; + } + + @Override + public long computePart2(List<String> data) { + return 0; + } + + private List<Stack<Character>> createStacks(List<String> data) { + Integer rowWithIndices = null; + int i = 0; + while (rowWithIndices == null) { + if (data.get(i).startsWith(" 1")) { + rowWithIndices = i; + } + i++; + } + String[] indexStrings = data.get(rowWithIndices).strip().split(" "); + int numberOfStacks = Integer.parseInt(indexStrings[indexStrings.length - 1]); + List<Stack<Character>> stacks = new ArrayList<>(numberOfStacks); + for (i = 0; i < numberOfStacks; i++) { + stacks.add(new Stack<>()); + } + for (i = rowWithIndices - 1; i >= 0; i--) { + for (int stack = 0; stack < numberOfStacks; stack++) { + char crate = data.get(i).charAt(4 * stack + 1); + if (crate != ' ') { + stacks.get(stack).push(crate); + } + } + } + return Collections.unmodifiableList(stacks); + } + + private void rearrangeCrates(List<Stack<Character>> stacks, List<String> data) { + for (String instruction : data) { + if (instruction.startsWith("move")) { // then it really is an instruction + String[] tokens = instruction.strip().split(" "); + int numberOfCratesToMove = Integer.parseInt(tokens[1]); + for (int i = 0; i < numberOfCratesToMove; i++) { + int source = Integer.parseInt(tokens[3]) - 1; // -1 because the original stacks were 1-indexed + int destination = Integer.parseInt(tokens[5]) - 1; + char crate = stacks.get(source).pop(); + stacks.get(destination).push(crate); + } + } + } + } + + private String getTopsOfStacks(List<Stack<Character>> stacks) { + StringBuilder stringBuilder = new StringBuilder(); + for (Stack<Character> stack : stacks) { + if (stack.empty()) { + stringBuilder.append(' '); // this isn't in the spec, but we'll go with it for now + } else { + Character crate = stack.pop(); + stack.push(crate); // leave it the way we found it + stringBuilder.append(crate); + } + } + return stringBuilder.toString(); + } +}