Walk on Matrix using pseudocode
tldr; if you visualize walk in matrix, it looked like playing snake moving inward spiral motion starting at top left and ends somewhere in the middle.
Code implemented in Elixir can be found here
Intro
Walk in Matrix is a coding puzzle in which you are given an input of 2-dimensional list of integers and returns a list of integers.
The input is something like this:
[
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
Then the output:
[1, 2, 3, 6, 9, 8, 7, 4, 5]
Before we start, some caveats:
- We'll only talk in pseudocode.
- This walkthrough won't cover about optimizations or anything that has something to do for-the-holy-grail of speed nor efficiency!
- We won't explain here why recursion exists nor its purpose. Tip: search thru internet "recursion eli5" or "recursion illustration examples" (you get what I mean).
Here's the 6 magical "steps" to walk in the matrix
1) Think, think!
- Must be a nested list
- Each row (list) has the same amount of elements.
- Also, we're gonna add some fancy words:
head
andtail
.
Here's what a nested list, visualized:
[
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
Note: as you may noticed, list contains numbers. We're going to stick with numbers for the sake of convenience. Pay close attention to those square brackets ([
]
).
What do head
and tail
look like?
head
is when you take the first element from a list. In that case the head
here is:
[1, 2, 3]
Whoa, I thought "first element" you say? Yes, [1, 2, 3]
is the first element. As "first element" means it is either a single one OR lots of it BUT grouped as one. As you see, [1, 2, 3]
is a list that contains 3 numbers where it is separated by comma (,
). It just so happened that the first element was a list! and the separator for the rest of it is by adding a comma (,
).
Now tail
, on the other hand, is another way of saying "the rest or what's left after you take out the first element".
What does a tail
look like?
[
[4, 5, 6],
[7, 8, 9]
]
Aside from head
and tail
, we should make another group called sorted
and unsorted
. What this means is that the correct order of numbers are to be put in sorted
while the rest is in unsorted
. This unsorted
group will eventually be moved to sorted
.
here's our current state:
[
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
sorted = []
unsorted = []
2) Move, move!
So we're going to start at the head. Move the leftmost element and put it in the rightmost of sorted
group
[
[1, 2, 3], <- this is the head
[4, 5, 6],
[7, 8, 9]
]
our head sorted unsorted
[1, 2, 3] [] []
[2, 3] [1] []
[3] [2, 1] []
[] [3, 2, 1] []
Howdy, wait! it looks like we just reversed the order of those numbers!
here's our current state:
head = []
sorted = [3, 2, 1]
unsorted = []
tail =
[
[4, 5, 6],
[7, 8, 9]
]
3) Put it here, put it there
Remember tail
? Currenly our tail looks like this
[
[4, 5, 6],
[7, 8, 9]
]
We're going to put elements of tail into 2 groups:
- The last element of each list should go in
sorted
- The rest goes in
unsorted
Don't do anything on the very last list, as we'll use that on the next step
The "recursion" part starts here (step #3) inside the unsorted
until none is left. So here's step-by-step walkthrough:
[
[4, 5, 6], <- do this
[7, 8, 9] <- don't touch this last list
]
row sorted unsorted
[4, 5, 6] [3, 2, 1] []
[4, 5] [6, 3, 2, 1] []
[4] [6, 3, 2, 1] [4]
[] [6, 3, 2, 1] [5, 4]
here's our current state:
[
[7, 8, 9]
]
head = []
sorted = [6, 3, 2, 1]
unsorted = [5, 4]
tail =
[
[7, 8, 9]
]
4) Put it exactly as it should be
When you reach at the last row of tail, just copy as it is.
[
[7, 8, 9] <- last row
]
row sorted unsorted
[7, 8, 9] [6, 3, 2, 1] [5, 4]
[] [7, 8, 9, 6, 3, 2, 1] [5, 4]
here's our current state:
[
]
head = []
sorted = [7, 8, 9, 6, 3, 2, 1]
unsorted = [5, 4]
tail = []
5) Everyday I'm shufflin'
Once you're done with step #4 (aka last row), go back to step #2 and keep doing this until unsorted
is empty. Take note, we still have elements in unsorted
.
So unsorted
elements will be moved to "head":
[
[4, 5] <- go back to step #2, unsorted is now "head"
]
row sorted unsorted
[4, 5] [7, 8, 9, 6, 3, 2, 1] []
[5] [4, 7, 8, 9, 6, 3, 2, 1] []
[] [5, 4, 7, 8, 9, 6, 3, 2, 1] []
Since unsorted
is now empty, we're moving to the final step.
6) Reverse UNO!
Once unsorted
is empty, now we reverse the sorted
list in order to get the final output.
from:
[5, 4, 7, 8, 9, 6, 3, 2, 1]
to:
[1, 2, 3, 6, 9, 8, 7, 4, 5]
So that's it! I hope you enjoyed this walkthrough. I didn't cramps during the session. But if you're tired, you can see the actual implementation in Elixir here.