Woo boy! Day 5 gave me issues.
First off, when I copied my framework I’m using, I didn’t want trailing newlines, so I added a .trim()
to the return line for the function that gets the input. This problem has spaces at the beginning. So, I fixed it by replacing trim with replace(/[\r\n]+$, '')
. And I discovered trying to figure how to parse the initial state of the crates!
That combine with trying to parse the initial stack of crates, I spend like 40 minutes working on today’s problem.
Parsing the input
Working at midnight is not fun. So, I know I didn’t do this well. Maybe overdid it.
First I did a split on the blank like, then used map() to split the two elements by line breaks, something you’ll see in my code during the events when I need to split on a blank line.
const data = d.split('\n\n').map(e=> e.split('\n'));
Then I need to create the stacks, so I made an array to contain it, used a crazy line to get the last column from the last line of the initial stack, then used a loop to add empty arrays to the stack variable to have the columns for each stack.
const crateStack = [];
const columns = parseInt(data[0].pop().match(/(\d)/g).pop(), 10);
for(let i = 0; i < columns; i++) {
crateStack.push([]);
}
Having fun yet? When I wrote it, I learned about matchAll
… Unlike the match
, it doesn’t return an array, so I use some newer features of JavaScript to basically convert it to an array, and since I used a regex with grouping, I basically made a multidimensional array, and reversed it, so I would use pop
and push
instead of the shift
and unshift
pairs of functions when I go to move the crates.
Then I just toss the results into the stack array, ignoring spaces (Remember about trim? The example and my input made at least the first stack shorter than the rest, and there are spaces at the beginning of the file that was removed.)
data[0] = data[0]
.map(e => [...e.matchAll(/[ []([A-Z ])[\] ] ?/g)].map(e=> e[1]))
.reverse();
data[0].forEach(row => {
row.forEach((crate, column) => {
if (crate !== ' ') {
crateStack[column].push(crate);
}
});
});
Moving crates
Looped through the commands, and did the steps.
Part 1 used an inner for loop to move the crates one at a time, so I pop
off the source and push
on the destination.
data[1].forEach(command => {
const moves = command.match(/move (\d+) from (\d+) to (\d+)/).map(e => parseInt(e, 10));
for (let i = 0; i < moves[1]; i++) {
const crate = crateStack[moves[2] - 1].pop();
crateStack[moves[3] - 1].push(crate);
}
});
Part 2, no for loop, but used splice
(with a negative value) instead of pop
data[1].forEach(command => {
const moves = command.match(/move (\d+) from (\d+) to (\d+)/).map(e => parseInt(e, 10));
const crates = crateStack[moves[2] - 1].splice(-moves[1]);
crateStack[moves[3] - 1].push(...crates);
});
Both parts shared the same return statment
return crateStack.reduce((p,v) => p + v.pop(), '');
Small code for the amount of work I put into it: aoc2022/05.js at main · miquelfire/aoc2022 · GitHub