Auto-rotación binaria

13

Dada una matriz binaria en 3D, para cada capa, gire cíclicamente cada una de sus columnas tantos pasos como lo indica la codificación binaria de las columnas de la capa encima de ella, y luego gire cíclicamente a la izquierda cada una de sus filas tantos pasos como lo indique La codificación binaria de las filas de la capa debajo de ella.

Siempre habrá al menos tres capas. Las columnas de la capa superior y las filas de la capa inferior no deben rotarse.

Recorrido

Comencemos con la pequeña matriz de 4 capas, 2 filas y 3 columnas:

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

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

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

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

El primer paso es evaluar los números codificados en binario por las columnas y filas de cada capa:

     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]]]

La primera capa, [[1,0,1],[1,0,0]]no tendrá sus columnas giradas, pero sus filas serán rotadas cíclicamente a la izquierda 5 pasos y 3 pasos respectivamente, convirtiéndose así [[1,1,0],[1,0,0]].
 La segunda capa, [[1,0,1],[0,1,1]]tendrá sus columnas giradas cíclicamente 3, 0 y 2 pasos respectivamente, dando [[0,0,1],[1,1,1]], y luego las filas se girarán cíclicamente 3 y 7 pasos respectivamente, sin cambio visible.
 La tercera capa, [[0,1,1],[1,1,1]]girada hacia arriba 2, 1 y 3 pasos, permanece igual, y tampoco lo hace la rotación hacia la izquierda 6 y 7 pasos.
 Finalmente, la cuarta capa, [[1,1,0],[1,1,1]]rotada 1, 3 y 3 pasos es [[1,1,1],[1,1,0]], pero sus filas no se giran después, ya que es la última capa.
 Al volver a juntar todas las capas, se obtiene la matriz binaria de rotación automática en 3D:

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

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

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

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

Casos de ejemplo:

[[[1,0,1],[1,0,0]],[[1,0,1],[0,1,1]],[[0,1,1],[1,1,1]],[[1,1,0],[1,1,1]]] da
[[[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]]] da
[[[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]]] da
[[[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]]]

Adán
fuente

Respuestas:

3

Jalea ,  18  17 bytes

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

Pruébalo en línea!

¿Cómo?

ṙ""Ḅ} - 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) )

Nota: $$(¿o posiblemente $$ ... $$?) Parece estropear el formato del bloque de código (pero solo una vez publicado, no en la vista previa), por lo que agregué un espacio para facilitarme la vida.

Jonathan Allan
fuente
3

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

Pruébalo en línea!

-2 bytes, gracias a Jonathan Allan

TFeld
fuente
Dado que manejas Nonedurante el corte para la rotación, creo que ambos ['0']pueden convertirse [[]].
Jonathan Allan
@JonathanAllan Gracias :)
TFeld
2

APL + WIN, 53 39 bytes

Muchas gracias a Adám por guardar 14 bytes.

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

Pruébalo en línea! Cortesía de Dyalog Classic.

Solicita la entrada de una matriz 3D del formulario:

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

cuyos rendimientos:

1 0 1
1 0 0

1 0 1
0 1 1

0 1 1
1 1 1

1 1 0
1 1 1

Explicación:

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
Graham
fuente
En lugar de encerrar y usar ¨, simplemente procese toda la matriz a la vez. Pruébalo en línea!
Adám
@ Adám Muchas gracias. No sé por qué pensé demasiado en este y tomé la ruta anidada :( ¿Envejeciendo?
Graham
2

R , 226 216 205 bytes

-21 bytes gracias a 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}

Pruébalo en línea!

Solo ASCII
fuente
1

05AB1E , 41 39 bytes

εNĀiø¹N<èøJC‚øε`._}ø}N¹g<Êi¹N>èJC‚øε`._

Esto se siente demasiado tiempo ... Definitivamente se puede jugar un poco más.

Pruébelo en línea o verifique todos los casos de prueba .

Explicación:

ε                    # 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
    ¹N             #   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
 N¹gi              #  If this is not the last layer (layer-index-1 != amount_of_layers):
       ¹N          #   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)
Kevin Cruijssen
fuente
0

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}&

Pruébalo en línea!

  • Map[Thread]es equivalente a Transpose[a, {1,3,2}], que transpone las columnas y filas.
  • Fold[#+##&]es más corto que IntegerDigits[#,2]para convertir de binario.
lirtosiast
fuente