I have a 3-dimensional array. Think of it as a brick. There are 24 possible rotations of this brick (that keep its edges parallel to coordinate axes). How do I generate all corr
James Waldby's answer is inspiring, and I want to add a slightly improved version with only two for-loops.
We know that there are 24 unique orientations. I calculated this by imagining a dice: there are 6 possible choices for the top face, and 4 possible rotations for each face on top.
What if we iterate with that idea? I thought. If we can figure out a way to travel all 6 faces of the dice, then we only need to observe the 4 rotations on each face, and we are done!
So I grabbed the nearest "brick" (in my case, a Vitasoy carton) and started rotating to see what would be the easiest pattern to visit all 6 faces. If we introduce an additional counter-clockwise turn, such that our operations are:
Then we can visit all faces by doing:
Roll -> Turn CW -> Roll -> Turn CCW -> Roll -> Turn CW -> Roll -> Turn CCW -> Roll -> Turn CW -> Roll -> Turn CCW
With the last roll and turn, we are back to the original orientation. As you can see, it is a repeated sequence of roll + alternating CW turns and CCW turns.
Now, if we expand this to include all rotations of each face we visit, this becomes:
Roll -> 3x Turn CW -> Roll -> 3x Turn CCW -> Roll -> 3x Turn CW -> Roll -> 3x Turn CCW -> Roll -> 3x Turn CW -> Roll -> 3x Turn CCW
...and we are back to where we started! This can be translated into two for-loops (one fewer!):
def sequence(m):
for roll_index in range(6):
m = roll(m)
yield(m)
for turn_index in range(3):
m = turn_cw(m) if roll_index % 2 == 0 else turn_ccw(m)
yield(m)