Auto-rotação binária

13

Dada uma matriz 3D binária, para cada camada, gire ciclicamente cada uma de suas colunas tantas etapas, conforme indicado pela codificação binária das colunas da camada acima dela, e gire ciclicamente à esquerda de cada uma de suas linhas, quantas etapas forem indicadas por a codificação binária das linhas da camada abaixo dela.

Sempre haverá pelo menos três camadas. As colunas da camada superior e as linhas da camada inferior não devem ser giradas.

Walk-through

Vamos começar com a pequena matriz de 4 camadas, 2 linhas e 3 colunas:

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

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

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

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

A primeira etapa é avaliar os números codificados em binário pelas colunas e linhas de cada camada:

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

A primeira camada [[1,0,1],[1,0,0]]não terá suas colunas rotacionadas, mas suas linhas serão rotacionadas ciclicamente para a esquerda 5 etapas e 3 etapas respectivamente, tornando-se assim [[1,1,0],[1,0,0]].
 A segunda camada [[1,0,1],[0,1,1]],, terá suas colunas giradas ciclicamente para cima 3, 0 e 2 etapas respectivamente, fornecendo [[0,0,1],[1,1,1]]e, em seguida, as linhas serão giradas ciclicamente para a esquerda 3 e 7 etapas respectivamente, sem alteração visível.
 A terceira camada, [[0,1,1],[1,1,1]]girada para cima 2, 1 e 3 etapas, permanece a mesma e a rotação esquerda 6 e 7 não faz nada.
 Finalmente, a quarta camada, [[1,1,0],[1,1,1]]girada para cima 1, 3 e 3 etapas [[1,1,1],[1,1,0]], é , mas suas linhas não são giradas depois, como é a última camada.
 Juntar todas as camadas novamente, fornece a matriz 3D auto-rotativa binária:

[[[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 exemplo:

[[[1,0,1],[1,0,0]],[[1,0,1],[0,1,1]],[[0,1,1],[1,1,1]],[[1,1,0],[1,1,1]]]
[[[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]]]
[[[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]]]
[[[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ão
fonte

Respostas:

3

Geléia ,  18  17 bytes

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

Experimente online!

Quão?

ṙ""Ḅ} - 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: $$(ou possivelmente $$ ... $$?) Parece atrapalhar a formatação do bloco de código (mas apenas uma vez postada, não na visualização), então adicionei um espaço para facilitar minha vida.

Jonathan Allan
fonte
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

Experimente online!

-2 bytes, graças a Jonathan Allan

TFeld
fonte
Desde que você lida com Noneo corte para a rotação, acredito que ambos ['0']podem se tornar [[]].
Jonathan Allan
Graças @JonathanAllan :)
TFeld
2

APL + WIN, 53 39 bytes

Muito obrigado a Adám por salvar 14 bytes

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

Experimente online! Cortesia de Dyalog Classic

Solicita a entrada de uma matriz 3d do formulário:

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

que produz:

1 0 1
1 0 0

1 0 1
0 1 1

0 1 1
1 1 1

1 1 0
1 1 1

Explicação:

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
fonte
Em vez de incluir e usar ¨, apenas processe toda a matriz de uma só vez. Experimente online!
Adám 22/01/19
@ Adám Muito obrigado. Eu não sei por que eu mais pensei que este e foi a rota aninhada :( Envelhecer?
Graham
2

R , 226 216 205 bytes

-21 bytes graças 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}

Experimente online!

Somente ASCII
fonte
1

05AB1E , 41 39 bytes

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

Isso parece muito longo .. Definitivamente pode ser jogado um pouco mais.

Experimente online ou verifique todos os casos de teste .

Explicação:

ε                    # 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
fonte
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}&

Experimente online!

  • Map[Thread]é equivalente a Transpose[a, {1,3,2}], que transpõe as colunas e linhas.
  • Fold[#+##&]é mais curto do que IntegerDigits[#,2]para converter de binário.
lirtosiast
fonte