Advent of Code 2022 Day 5
Try the Simulator using your puzzle input!
Part 1
- Save for later
- Manually re-creating the stack of crates
- Programming the crane
- Loop and adjust everything by 1
- My algorithm in JavaScript
Save for later
- I intend to build a simulator for today's puzzle
- To do that, I'll need to programmatically build the stack of crates
- I'm excited to build that algorithm
- But I'm more excited to attempt solving the puzzle for my own input
Manually re-creating the stack of crates
To programmatically represent the example input:
[D]
[N] [C]
[Z] [M] [P]
1 2 3
I will use a nested list data structure:
[
['Z', 'N'],
['M', 'C', 'D'],
['P']
]
Programming the crane
After the crates are rearranged, the desired crates will be at the top of each stack.
There are four ways to adjust the amount of items in a list at either end:
- Insert at the end
- Insert at the beginning
- Remove from the end
- Remove from the beginning
It seems like this puzzle calls for these two:
- Remove from the end
- Insert at the end
In JavaScript, those are represented as:
pop()
push()
A command like move 3
would perform the following operations:
pop()
push()
pop()
push()
pop()
push()
Loop and adjust everything by 1
Each command references stacks using 1-based indices:
move 3 from 1 to 3
In pseudocode, I need to:
Do three times
pop() from stack 0
push() to stack 2
My algorithm in JavaScript
// stacks = [ [...], [...], [...] ]
input
.split('\n\n')[1]
.split('\n')
.forEach(cmd => {
let [times, from, to] = [
...cmd.matchAll(/\d+/g)
].map(match => +match[0])
for (let i = times; i > 0; i--) {
let crate = stacks[from - 1].pop()
stacks[to - 1].push(crate)
}
})
return stacks.map(s => s[s.length - 1]).join('')
Part 2
- Method swaps
- My algorithm in JavaScript
Method swaps
-
pop()
forsplice()
-
push()
forconcat()
pop()
for splice()
-
pop()
removes the last element -
splice()
removes several elements
push()
for concat()
-
push()
adds one element -
concat()
combines multiple arrays into a single array
Using this example again:
move 3 from 1 to 3
In pseudocode, I need to:
splice(3 from the end) from stack 0
concat(stack 2 with 3 from the end)
My algorithm in JavaScript
// stacks = [ [...], [...], [...] ]
input
.split('\n\n')[1]
.split('\n')
.forEach(cmd => {
let [times, from, to] = [
...cmd.matchAll(/\d+/g)
].map(match => +match[0])
let crates = stacks[from - 1].splice(-times)
stacks[to - 1] = stacks[to - 1].concat(crates)
})
return stacks.map(s => s[s.length - 1]).join('')
Saved for later
I want to programmatically build the stack of crates.
- Analyzing the input
- My algorithm in pseudocode
- My algorithm in JavaScript
Analyzing the input
[D]
[N] [C]
[Z] [M] [P]
1 2 3
- The letters appear at indices: 1, 5, 9
- The rows at the bottom are the crates earliest in the stack
- The first row is useless for my purposes
My algorithm in pseudocode
Split the multi-line string into an array of strings
Reverse the array to put rows in their insertion order
Remove the first row containing the column numbers
For each row
Start at the second character (index 1)
Skip 4 characters each iteration
Go until moving passed the end of the string
If there's no nested array corresponding to the current column
Create an empty one
If the current character is anything other than a string with a single space
Add the character to the appropriate nested array
My algorithm in JavaScript
let stacks = []
input
.split('\n\n')[0]
.split('\n')
.reverse()
.slice(1)
.forEach(line => {
for (let i = 1; i < line.length; i += 4) {
if (typeof stacks[(i - 1) / 4] !== 'object') {
stacks.push([])
}
if (line[i] !== ' ') {
stacks[(i - 1) / 4].push(line[i])
}
}
})
Building the simulator
Now that I have:
- Solved Part 1
- Solved Part 2
- Programmatically built the stack of crates
It's time to build a simulator of the CrateMover 9000 and 9001!
...
How it went:
- Pretty smoothly overall
- I got stuck wondering why it wasn't working
- Then I realized I forgot to replace my loops with performing a single command each time!
The fun bit of code is in rendering the crates after each command:
stacks.map(
row => row.map(
el => `[${el}]`
).join('')
).join('\n')
Try the Simulator using your puzzle input!
I did it!!
- I solved both parts!
- I re-created the stacks of crates algorithmically!
- I built my first simulator of the year!
I was initially concerned that this would be a shortest path
puzzle, given the rearranging of items.
Thankfully, since it is only Day 5, it was a different challenge type: list manipulation.
Still a fun one that gave me more practice!
Top comments (0)