Auto-rotation binaire

13

Étant donné un tableau binaire 3D, pour chaque couche, faites pivoter cycliquement vers le haut chacune de ses colonnes autant d'étapes que l'indique le codage binaire des colonnes de la couche au-dessus, puis faites pivoter cycliquement vers la gauche chacune de ses lignes autant d'étapes que l'indique l'encodage binaire des lignes de la couche en dessous.

Il y aura toujours au moins trois couches. Les colonnes de la couche supérieure et les lignes de la couche inférieure ne doivent pas être tournées.

Procédure pas à pas

Commençons par le petit tableau à 4 couches, 2 lignes et 3 colonnes:

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

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

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

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

La première étape consiste à évaluer les nombres encodés en binaire par les colonnes et les lignes de chaque couche:

     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 première couche, [[1,0,1],[1,0,0]]n'aura pas ses colonnes tournées, mais ses rangées seront tournées cycliquement à gauche de 5 étapes et 3 étapes respectivement, devenant ainsi [[1,1,0],[1,0,0]].
 La deuxième couche,, [[1,0,1],[0,1,1]]verra ses colonnes pivotées cycliquement respectivement de 3, 0 et 2 pas, ce qui donnera [[0,0,1],[1,1,1]], puis les rangées seront pivotées cycliquement de 3 et 7 pas respectivement, sans changement visible.
 La troisième couche, [[0,1,1],[1,1,1]]tournée de 2, 1 et 3 pas vers le haut, reste la même, et la rotation des pas de 6 et 7 vers la gauche ne fait rien non plus.
 Enfin, la quatrième couche, [[1,1,0],[1,1,1]]tournée de 1, 3 et 3 étapes, l'est [[1,1,1],[1,1,0]], mais ses rangées ne sont pas tournées par la suite, comme c'est la dernière couche.
 Remettre toutes les couches ensemble, nous donne le tableau 3D auto-tourné binaire:

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

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

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

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

Exemples de cas:

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

Adam
la source

Réponses:

3

Gelée ,  18  17 octets

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

Essayez-le en ligne!

Comment?

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

Remarque: $$(ou peut $$ ... $$- être ?) Semble perturber le formatage du bloc de code (mais seulement une fois publié, pas dans l'aperçu), j'ai donc ajouté un espace pour me faciliter la vie.

Jonathan Allan
la source
3

Python 2 , 220 211 209 209 185 176 174 164 161 161 159 octets

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

Essayez-le en ligne!

-2 octets, merci à Jonathan Allan

TFeld
la source
Puisque vous gérez Nonependant le découpage pour la rotation, je crois que les deux ['0']peuvent devenir [[]].
Jonathan Allan
@JonathanAllan Merci :)
TFeld
2

APL + WIN, 53 39 octets

Un grand merci à Adám pour économiser 14 octets

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

Essayez-le en ligne! Gracieuseté de Dyalog Classic

Invite à saisir un tableau 3D de la forme:

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

ce qui donne:

1 0 1
1 0 0

1 0 1
0 1 1

0 1 1
1 1 1

1 1 0
1 1 1

Explication:

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
la source
Au lieu d'enfermer et d'utiliser ¨, il suffit de traiter l'ensemble du tableau à la fois. Essayez-le en ligne!
Adám
@ Adám Merci beaucoup. Je ne sais pas pourquoi j'ai trop réfléchi à celui-ci et j'ai emprunté la voie imbriquée :( Vieillir?
Graham
2

R , 226 216 205 octets

-21 octets grâce à 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}

Essayez-le en ligne!

ASCII uniquement
la source
1

05AB1E , 41 39 octets

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

Cela semble beaucoup trop long. Peut certainement être joué au golf encore plus.

Essayez-le en ligne ou vérifiez tous les cas de test .

Explication:

ε                    # 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
la source
0

Wolfram Language (Mathematica) , 138 131 125 123 octets

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

Essayez-le en ligne!

  • Map[Thread] est équivalent à Transpose[a, {1,3,2}] , qui transpose les colonnes et les lignes.
  • Fold[#+##&]est plus court que IntegerDigits[#,2]pour la conversion de binaire.
lirtosiast
la source