15
\$\begingroup\$

Given a binary 3D array, for each layer, cyclically rotate up each of its columns as many steps as indicated by the binary encoding of the columns of the layer above it, and then cyclically rotate left each of its rows as many steps as indicated by the binary encoding of the rows of the layer below it.

There will always be at least three layers. The top layer's columns and the bottom layer's rows should not be rotated.

Walk-through

Lets start with the small 4-layer, 2-row, 3-column array:

[[[1,0,1],
 [1,0,0]],
 [[1,0,1],
 [0,1,1]],
 [[0,1,1],
 [1,1,1]],
 [[1,1,0],
 [1,1,1]]]

The first step is evaluating the numbers encoded in binary by the columns and rows of each layer:

 3 0 2
5 [[[1,0,1],
4 [1,0,0]],
 2 1 3
5 [[1,0,1],
3 [0,1,1]],
 1 3 3
3 [[0,1,1],
7 [1,1,1]],
 3 3 1
6 [[1,1,0],
7 [1,1,1]]]

The first layer, [[1,0,1],[1,0,0]] will not have its columns rotated, but its rows will be cyclically rotated left 5 steps and 3 step respectively, thus becoming [[1,1,0],[1,0,0]].
The second layer, [[1,0,1],[0,1,1]], will have its columns cyclically rotated up 3, 0, and 2 steps respectively, giving [[0,0,1],[1,1,1]], and then the rows are cyclically rotated left 3 and 7 steps respectively, with no visible change.
The third layer, [[0,1,1],[1,1,1]] rotated up 2, 1, and 3 steps stays the same, and neither does rotating left 6 and 7 steps do anything.
Finally, the fourth layer, [[1,1,0],[1,1,1]] rotated up 1, 3, and 3 steps is [[1,1,1],[1,1,0]], but its rows are not rotated afterwards, as it is the last layer.
Putting all the layers together again, gives us the binary self-rotated 3D array:

[[[1,1,0],
 [1,0,0]],
 [[0,0,1],
 [1,1,1]],
 [[0,1,1],
 [1,1,1]],
 [[1,1,1],
 [1,1,0]]]

Example cases:

[[[1,0,1],[1,0,0]],[[1,0,1],[0,1,1]],[[0,1,1],[1,1,1]],[[1,1,0],[1,1,1]]] gives
[[[1,1,0],[1,0,0]],[[0,0,1],[1,1,1]],[[0,1,1],[1,1,1]],[[1,1,1],[1,1,0]]]

[[[1]],[[1]],[[0]]] gives
[[[1]],[[1]],[[0]]]

[[[1,0,1],[1,0,1],[1,0,1]],[[0,0,1],[0,0,1],[0,0,1]],[[1,0,0],[1,0,1],[0,0,1]]] gives
[[[0,1,1],[0,1,1],[0,1,1]],[[0,1,0],[1,0,0],[0,1,0]],[[1,0,1],[1,0,1],[0,0,0]]]

asked Jan 22, 2019 at 9:00
\$\endgroup\$

8 Answers 8

3
\$\begingroup\$

Jelly, (削除) 18 (削除ここまで) 17 bytes

ṙ""Ḅ}
Z€çŻṖ$$Z€çḊ

Try it online!

How?

ṙ""Ḅ} - Link 1, rotation helper: 3d matrix to rotate, 3d matrix of rotation instructions
 } - use the right argument for:
 Ḅ - un-binary (vectorises) - get the rotation amounts as a 2d matrix
 " - zip with:
 " - zip with:
ṙ - rotate (the current row) left by (the current amount)
Z€çŻṖ$ $Z€çḊ - Main Link: 3d matrix, M
Z€ - transpose €ach (layer of M)
 $ - last two links as a monad:
 $ - last two links as a monad:
 Ż - prepend a zero
 Ṗ - pop (i.e. remove the tail)
 ç - call the last Link as a dyad (i.e. f(Z€ result, ŻṖ$ result) )
 Z€ - transpose €ach (layer of that)
 Ḋ - dequeue (i.e. remove the head layer of M)
 ç - call the last Link as a dyad (i.e. f(Z€çŻṖ$$Z€ result, Ḋ result) )

Note: $$ (or possibly $$ ... $$?) seems to mess up the code-block formatting (but only once posted, not in the preview), so I added a space to make my life easier.

answered Jan 22, 2019 at 13:27
\$\endgroup\$
3
\$\begingroup\$

Python 2, (削除) 220 (削除ここまで) (削除) 211 (削除ここまで) (削除) 209 (削除ここまで) (削除) 185 (削除ここまで) (削除) 176 (削除ここまで) (削除) 174 (削除ここまで) (削除) 164 (削除ここまで) (削除) 161 (削除ここまで) 159 bytes

lambda m:map(R,z(map(R,z(m,['']+[z(*l)for l in m])),m[1:]+['']))
R=lambda(l,L):map(lambda r,i:r[i:]+r[:i or 0],z(*l),[int(`b`[1::3],2)%len(b)for b in L])
z=zip

Try it online!

-2 bytes, thanks to Jonathan Allan

answered Jan 22, 2019 at 14:08
\$\endgroup\$
2
  • \$\begingroup\$ Since you handle None during the slicing for the rotation I believe both of the ['0'] can become [[]]. \$\endgroup\$ Commented Jan 22, 2019 at 17:29
  • \$\begingroup\$ @JonathanAllan Thanks :) \$\endgroup\$ Commented Jan 23, 2019 at 8:01
2
\$\begingroup\$

APL+WIN, (削除) 53 (削除ここまで) 39 bytes

Many thanks to Adám for saving 14 bytes

(1 0↓⍉2⊥⍉m⍪0)⌽( ̄1 0↓2⊥2 1 3⍉0⍪m)⊖[2]m←⎕

Try it online! Courtesy of Dyalog Classic

Prompts for input of a 3d array of the form:

4 2 3⍴1 0 1 1 0 0 1 0 1 0 1 1 0 1 1 1 1 1 1 1 0 1 1 1

which yields:

1 0 1
1 0 0
1 0 1
0 1 1
0 1 1
1 1 1
1 1 0
1 1 1

Explanation:

m←⎕ Prompt for input
( ̄1 0↓2⊥2 1 3⍉0⍪m) Calculate column rotations
(1 0↓⍉2⊥⍉m⍪0) Calculate row rotations
(...)⌽(...)⊖[2]m Apply column and row rotation and output resulting 3d array:
1 1 0
1 0 0
 
0 0 1
1 1 1
 
0 1 1
1 1 1
 
1 1 1
1 1 0
answered Jan 22, 2019 at 14:49
\$\endgroup\$
2
  • \$\begingroup\$ Instead of enclosing and using ¨, just process the entire array at once. Try it online! \$\endgroup\$ Commented Jan 22, 2019 at 17:08
  • \$\begingroup\$ @Adám Many thanks. I do not know why I over thought this one and went the nested route :( Getting old? \$\endgroup\$ Commented Jan 22, 2019 at 18:44
2
\$\begingroup\$

R, (削除) 226 (削除ここまで) (削除) 216 (削除ここまで) 205 bytes

-21 bytes thanks to digEmAll

function(a,L=`for`){d=dim(b<-a)
r=function(a,n,l=sum(a|1))a[(1:l+sum(n*2^(sum(n|1):1-1))-1)%%l+1]
L(i,I<-2:d[3],L(j,1:d,b[j,,i]<-r(b[j,,i],a[j,,i-1])))
L(i,I-1,L(k,1:d[2],b[,k,i]<-r(b[,k,i],a[,k,i+1])))
b}

Try it online!

answered Feb 23, 2019 at 1:11
\$\endgroup\$
0
1
\$\begingroup\$

05AB1E, (削除) 41 (削除ここまで) 39 bytes

εNĀiø1N<èøJC‚øε`._}ø}N1g<Êi1N>èJC‚øε`._

This feels way too long.. Can definitely be golfed some more.

Try it online or verify all test cases.

Explanation:

ε # Map each layer in the (implicit) input to:
 # (`N` is the layer-index of this map)
 NĀi # If it is not the first layer:
 ø # Zip/transpose the current layer; swapping rows/columns
 1N<è # Get the `N-1`'th layer of the input
 ø # Zip/transpose; swapping rows/columns
 J # Join all inner lists (the columns) together
 C # And convert it from binary to integer
 ‚ # Pair it with the current layer's columns we're mapping
 ø # Zip/transpose; to pair each integer with a layer's columns
 ε } # Map over these pairs:
 ` # Push both values of the pair separately to the stack
 ._ # Rotate the column the integer amount of times
 ø # Zip/transpose the rows/columns of the current layer back
 } # Close the if-statement
 N1g<Êi # If this is not the last layer (layer-index-1 != amount_of_layers):
 1N>è # Get the `N+1`'th layer of the input
 J # Join all inner lists (the rows) together
 C # And convert it from binary to integer
 ‚ # Pair it with the current layer's rows we're mapping
 ø # Zip/transpose; to pair each integer with a layer's rows
 ε # Map over these pairs:
 ` # Push both values of the pair separately to the stack
 ._ # Rotate the row the integer amount of times
 # (implicitly output the result after the layer-mapping is done)
answered Jan 22, 2019 at 9:56
\$\endgroup\$
1
\$\begingroup\$

Wolfram Language (Mathematica), (削除) 138 (削除ここまで) (削除) 131 (削除ここまで) (削除) 125 (削除ここまで) 123 bytes

t=Map@Thread
m=MapThread[r=RotateLeft,#,2]&
b=(a=ArrayPad)[Map@Fold[#+##&]/@#,1]~r~#2~a~-1&
g=m@{t@m@{t@#,t@#~b~-1},#~b~1}&

Try it online!

  • Map[Thread] is equivalent to Transpose[a, {1,3,2}], which transposes the columns and rows.
  • Fold[#+##&] is shorter than IntegerDigits[#,2] for converting from binary.
answered Jan 27, 2019 at 1:50
\$\endgroup\$
0
\$\begingroup\$

Uiua, (削除) 31 (削除ここまで) 29 bytes

≡≡↻⊙≡⍜∩⍉≡↻∩⬚0↻1⊙ ̄1∩°⋯∩≡≡⇌⟜≡⍉.

Try it out!

Explanation:

∩°⋯∩≡≡⇌⟜≡⍉.

Convert the rows and the columns to binary. (bits) uses little-endian binary, so the rows and the columns have to be reversed first.

∩⬚0↻1⊙ ̄1

Rotate the array of the columns up by one and the array of the rows down by one, filling with zeroes instead of cycling.

⊙≡⍜∩⍉≡↻

Rotate the columns.

≡≡↻

Rotate the rows.

answered Jul 25, 2024 at 22:03
\$\endgroup\$
0
\$\begingroup\$

J, (削除) 40 (削除ここまで) (削除) 38 (削除ここまで) 37 bytes

G=:{{|.~"p.u@1|.!.0#.}}
-G&.(1&|:)+G]

Attempt This Online!

Explanation:

The operation of rotating an array by its rows read as binary occurs twice if we consider the column-rotation to just be rotating the rows under transposing each matrix, so we extract it to a function G. However, in the row-rotation we shift the binary by -1 and in the column rotation we shift it by 1, so G has to be an explicit adverb in order to pass that third argument + or -.

G=:{{|.~"p.u@1|.!.0#.}} Define the adverb G. u is + or -
 |.~"p. Rotate the rows of the left array by
 #. the right array's rows read as binary,
 |.!.0 shifted, filling with zeroes, by
 u@1 u called on 1, so either 1 or _1

The second line is the function submission. It calls G twice, first under transposition of the matrices to rotate the rows, shifting down (-G&.(1&|:) and then using this as the array to rotate the columns of, shifting up (+G]).

answered Jul 26, 2024 at 16:05
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.