Advent of Code 2016 Day 8
Try the simulator using your puzzle input!
Part 1
- A look back at message-unscrambling puzzles
- Marquee tool, circular operations, and nested lists
- Extracting each instruction's important bits
- Building the skeleton of my
reduce()
- Handling rectangle instructions
- Handling row rotation instructions
- Handling column rotation instructions
- Revealing my message - and counting 'on' lights
A look back at message-unscrambling puzzles
- 2021 Day 13: Transparent Origami
- 2021 Day 8: Seven Segment Search
- 2019 Day 11: Space Police
- 2018 Day 10: The Stars Align
Hmm. I thought there were more.
Anyway:
- I had fun attempting each of those
- I solved both parts of each one
- I'm excited to attempt and solve this one!
Marquee tool, circular operations, and nested lists
This puzzle combines some familiar and novel concepts:
- String splitting or regular expressions to determine the instruction type, dimensions or row/column numbers and rotation amounts
- A marquee tool is represented by the continual selection of a rectangular subset of the grid from the top-left corner
- Circular operations are enacted by the rotation of values left-to-right wrapping and top-to-bottom wrapping
- Nested lists are the data structure I've always used to represent a grid of items
1,2 and 4 are simple enough by now.
3 seems simple - at least for row rotations.
But for column rotations, it may require some more complex programming.
Extracting each instruction's important bits
Example instructions include:
rect 14x1
rotate column x=12 by 1
rotate row y=0 by 40
If using string splitting, I can depend on:
- Items of length two to be rectangular selection instructions
- For all other instructions, I can discern column/row from the second phrase
Building the skeleton of my reduce()
I'll process each line using reduce()
.
That way, I can package the mutating grid and the instructions together.
The starting state of the accumulating grid should be a nested array whose length is 6 and whose nested arrays' lengths are 50...all filled with .
s.
My control flow therefore looks like:
input.reduce((grid, instruction) => {
let parts = instruction.split(' ')
if (parts.length == 2) {
// Rectangle-selection rule
} else if (parts[1] == 'column') {
// Column rotation rule
} else {
// Row rotation rule
}
}, new Array(6).fill(null).map(
el => new Array(50).fill(null).map(el => ' ')
)
)
Handling rectangle instructions
My algorithm as pseudocode:
After splitting the instruction string at each space character into an array
If the there are only two items in the array
Split the second item at the x
Coerce each string into a number
Store as width and height
Update the appropriate cells in the grid
Starting from the top-left corner
Setting each cell's value as #
My algorithm as JavaScript:
let parts = instruction.split(' ')
if (parts.length == 2) {
let [width, height] = parts[1].split('x').map(Number)
for (let row = 0; row < height; row++) {
for (let col = 0; col < width; col++) {
a[row][col] = "#"
}
}
}
Handling row rotation instructions
My algorithm as pseudocode:
After splitting the instruction string at each space character into an array
If no other conditions are true
Use a regular expression to match all integers
Store each integer as row and amount
For i from 0 to amount
Remove the last string in the nested array who's index matches row
Add it to the beginning of that array
My algorithm in JavaScript:
else {
let [row, amount] = [...c.matchAll(/\d+/g)].map(el => +el[0])
for (let i = 0; i < amount; i++) {
a[row].unshift(a[row].pop())
}
}
Handling column rotation instructions
My algorithm as pseudocode:
After splitting the instruction string at each space character into an array
If the second string is column
Use a regular expression to match all integers
Store each integer as column and amount
For each nested array
Extract the value from the appropriate column
Store an array called band containing all strings from the column in order from top to bottom
For i from 0 to amount
Remove the last string in the array
Add it to the beginning of the array
For each nested array
Update the value in the appropriate column with the corresponding string in the same index as the current nested array
My algorithm in JavaScript:
else if (parts[1] == 'column') {
let [column, amount] = [...c.matchAll(/\d+/g)]
.map(el => +el[0])
let band = a.map(row => row[column])
for (let i = 0; i < amount; i++) {
band.unshift(band.pop())
}
for (let row = 0; row < a.length; row++) {
a[row][column] = band[row]
}
}
Revealing my message - and counting 'on' lights
After storing the latest state of my grid as screen
:
return screen.map(el => el.join('')).join('\n')
- Mutate each nested array into a string of its concatenated characters
- Concatenate each string with a newline character
- Print the resulting multi-line string
Replacing all .
s with characters to better see the message:
#### ## ## ### ## ### # # # # ## ##
# # # # # # # # # # # # # # ## # # #
### # # # # # # # # # #### # # # # # #
# # # #### ### # ## ### # # # #### # #
# # # # # # # # # # # # # # # # #
#### ## # # # # ### # # # # # # ##
Using another double-reduce()
to count the #
characters:
screen.reduce(
(sum, line) => sum += line.reduce(
(sum, character) => sum += character == '#' ? 1 : 0
, 0)
, 0)
It counted 128 lights on
.
That was the correct answer!
Part 2
- I already revealed my message!
- And it was the correct answer!
Building a simulator to show each instruction
I created a new array called snapshots
:
let snapshots = []
In each of the three for
loops within my three conditions, I inserted a statement that added a stringified snapshot of the grid at each state - after a rectangular area was turned on, and after each single rotation.
By the time my reduce()
was done running, snapshots
would be full of strings representing a sort of stop-motion animation.
Indeed, it replays the instructions back as if in real-time!
I did it!!
- I solved both parts!
- For the first time, I solved Part 2 before Part 1, since I technically saw the message before I counted the amount of lights on!
- I built a simulator that replays the message reveal process like a stop-motion animation!
- I remain undefeated for all message-revealing puzzles!
Top comments (0)