Binäre Selbstrotation

13

Bei einem binären 3D-Array drehen Sie für jede Ebene zyklisch jede ihrer Spalten um so viele Schritte nach oben, wie durch die Binärcodierung der Spalten der darüber liegenden Ebene angegeben, und drehen Sie dann zyklisch jede ihrer Zeilen um so viele Schritte nach links, wie durch angegeben die binäre Kodierung der Zeilen der darunter liegenden Ebene.

Es wird immer mindestens drei Schichten geben. Die Spalten der obersten Ebene und die Zeilen der untersten Ebene sollten nicht gedreht werden.

Begehbar

Beginnen wir mit dem kleinen Array mit 4 Ebenen, 2 Zeilen und 3 Spalten:

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

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

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

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

Der erste Schritt besteht darin, die Zahlen auszuwerten, die in den Spalten und Zeilen jeder Ebene binär codiert sind:

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

Die [[1,0,1],[1,0,0]]Spalten der ersten Ebene werden nicht gedreht, die Zeilen werden jedoch zyklisch um 5 Schritte bzw. 3 Schritte nach links gedreht [[1,1,0],[1,0,0]].
 Bei der zweiten Ebene [[1,0,1],[0,1,1]]werden die Spalten zyklisch um 3, 0 bzw. 2 Schritte nach oben [[0,0,1],[1,1,1]]gedreht. Anschließend werden die Zeilen zyklisch um 3 bzw. 7 Schritte nach links gedreht, ohne dass eine Änderung erkennbar ist.
 Die dritte Ebene, die [[0,1,1],[1,1,1]]um 2, 1 und 3 Schritte nach oben gedreht wurde, bleibt unverändert, und die Schritte 6 und 7 nach links drehen hat keine Auswirkungen.
 Schließlich wird die vierte Ebene [[1,1,0],[1,1,1]]um 1, 3 und 3 Schritte nach oben gedreht [[1,1,1],[1,1,0]], aber ihre Reihen werden danach nicht gedreht, da es sich um die letzte Ebene handelt.
 Wenn Sie alle Ebenen erneut zusammenfügen, erhalten Sie das binäre, selbst gedrehte 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]]]

Beispielfälle:

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

Antworten:

3

Jelly ,  18  17 Bytes

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

Probieren Sie es online!

Wie?

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

Hinweis: $$(oder möglicherweise $$ ... $$?) Scheint die Codeblock-Formatierung durcheinander zu bringen (aber nur einmal veröffentlicht, nicht in der Vorschau), daher habe ich ein Leerzeichen hinzugefügt, um mein Leben zu erleichtern.

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

Probieren Sie es online!

-2 Bytes, danke an Jonathan Allan

TFeld
quelle
Da Sie Nonewährend des Schneidens für die Rotation sorgen, glaube ich, dass beide davon werden ['0']können [[]].
Jonathan Allan
@ JonathanAllan Dank :)
TFeld
2

APL + WIN, 53 39 Bytes

Vielen Dank an Adám für die Einsparung von 14 Bytes

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

Probieren Sie es online! Mit freundlicher Genehmigung von Dyalog Classic

Fordert zur Eingabe eines 3D-Arrays des Formulars auf:

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

was ergibt:

1 0 1
1 0 0

1 0 1
0 1 1

0 1 1
1 1 1

1 1 0
1 1 1

Erläuterung:

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
quelle
Anstatt ¨das Array einzuschließen und zu verwenden , verarbeiten Sie es einfach auf einmal. Probieren Sie es online!
Adám
@Adám Vielen Dank. Ich weiß nicht, warum ich über diesen Gedanken nachgedacht habe und den verschachtelten Weg gegangen bin :( Alt werden?
Graham
2

R , 226 216 205 Bytes

-21 Bytes dank 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}

Probieren Sie es online!

Nur ASCII
quelle
1

05AB1E , 41 39 Bytes

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

Das fühlt sich viel zu lang an. Kann definitiv noch mehr golfen werden.

Probieren Sie es online aus oder überprüfen Sie alle Testfälle .

Erläuterung:

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

Probieren Sie es online!

  • Map[Thread]ist äquivalent zu Transpose[a, {1,3,2}], was die Spalten und Zeilen transponiert.
  • Fold[#+##&]ist kürzer als IntegerDigits[#,2]für die Konvertierung von binär.
Lirtosiast
quelle