Binarna samoobrót

13

Biorąc pod uwagę binarną tablicę 3D, dla każdej warstwy cyklicznie obracaj w górę każdą jej kolumnę o tyle kroków, ile wskazuje kodowanie binarne kolumn warstwy nad nią, a następnie cyklicznie obracaj w lewo każdy z jej rzędów o tyle kroków, ile wskazuje binarne kodowanie wierszy warstwy poniżej.

Zawsze będą co najmniej trzy warstwy. Kolumny górnej warstwy i wiersze dolnej warstwy nie powinny być obracane.

Walk-through

Zacznijmy od małej 4-warstwowej, 2-rzędowej, 3-kolumnowej tablicy:

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

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

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

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

Pierwszym krokiem jest ocena liczb zakodowanych binarnie według kolumn i wierszy każdej warstwy:

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

Pierwsza warstwa [[1,0,1],[1,0,0]]nie będzie obracana kolumnami, ale jej rzędy będą cyklicznie obracane odpowiednio w lewo o 5 kroków i 3 kroki, stając się w ten sposób [[1,1,0],[1,0,0]].
 Druga warstwa, [[1,0,1],[0,1,1]]będzie miała swoje kolumny cyklicznie obracane odpowiednio o 3, 0 i 2 kroki, dając [[0,0,1],[1,1,1]], a następnie rzędy są cyklicznie obracane odpowiednio w lewo 3 i 7 kroków, bez widocznych zmian.
 Trzecia warstwa, [[0,1,1],[1,1,1]]obrócona w górę o 2, 1 i 3 kroki, pozostaje taka sama, a obracanie w lewo o 6 i 7 kroków nic nie robi.
 Wreszcie czwarta warstwa, [[1,1,0],[1,1,1]]obrócona o 1, 3 i 3 stopnie, jest [[1,1,1],[1,1,0]], ale jej rzędy nie są później obracane, ponieważ jest to ostatnia warstwa.
 Ponowne połączenie wszystkich warstw daje nam binarną samobrotową macierz 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]]]

Przykładowe przypadki:

[[[1,0,1],[1,0,0]],[[1,0,1],[0,1,1]],[[0,1,1],[1,1,1]],[[1,1,0],[1,1,1]]] daje
[[[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]]] daje
[[[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]]] daje
[[[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ám
źródło

Odpowiedzi:

3

Galaretka ,  18  17 bajtów

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

Wypróbuj online!

W jaki sposób?

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

Uwaga: $$(a może $$ ... $$?) Wydaje się, że psuje formatowanie bloku kodu (ale tylko raz opublikowane, nie w podglądzie), więc dodałem miejsce, aby ułatwić mi życie.

Jonathan Allan
źródło
3

Python 2 , 220 211 209 185 176 174 164 161 159 bajtów

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

Wypróbuj online!

-2 bajty, dzięki Jonathan Allan

TFeld
źródło
Ponieważ radzisz sobie Nonepodczas krojenia rotacji, uważam, że oba ['0']mogą się stać [[]].
Jonathan Allan
@JonathanAllan Thanks :)
TFeld
2

APL + WIN, 53 39 bajtów

Ogromne podziękowania dla Adáma za uratowanie 14 bajtów

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

Wypróbuj online! Dzięki uprzejmości Dyalog Classic

Monity o wprowadzenie tablicy 3d formularza:

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

co daje:

1 0 1
1 0 0

1 0 1
0 1 1

0 1 1
1 1 1

1 1 0
1 1 1

Wyjaśnienie:

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
źródło
Zamiast dołączać i używać ¨, wystarczy przetworzyć całą tablicę na raz. Wypróbuj online!
Adám
@ Adám Wielkie dzięki. Nie wiem, dlaczego to przemyślałem i wybrałem zagnieżdżoną trasę :( Starzeje się?
Graham,
2

R , 226 216 205 bajtów

-21 bajtów dzięki 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}

Wypróbuj online!

Tylko ASCII
źródło
1

05AB1E , 41 39 bajtów

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

Wydaje się, że jest to zdecydowanie za długo.

Wypróbuj online lub sprawdź wszystkie przypadki testowe .

Wyjaśnienie:

ε                    # 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
źródło
0

Wolfram Language (Mathematica) , 138 131 125 123 bajtów

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

Wypróbuj online!

  • Map[Thread]jest równoważne z Transpose[a, {1,3,2}], co transponuje kolumny i wiersze.
  • Fold[#+##&]jest krótszy niż w IntegerDigits[#,2]przypadku konwersji z pliku binarnego.
lirtosiast
źródło