Zeichnen Sie ein indiziertes Fraktal

14

Einführung

In dieser Herausforderung wird eine 2 × 2-Matrix wie folgt indiziert:

0 1
2 3

Wir definieren eine Familie von fraktalen Mustern F(L), wobei Les sich um eine Längenliste ndieser Indizes handelt und F(L)die Größe hat .2n-1 × 2n-1

  • Wenn ja L == [], dann F(L)ist das 1 × 1-Muster #.
  • Wenn L != [], dann F(L)ist wie folgt aufgebaut. Sei Pdas Muster, von dem das Lerste Element entfernt wurde. Nehmen Sie vier mit Punkten gefüllte Raster und ersetzen Sie das mit dem Muster indizierte Raster . Kleben Sie dann die Gitter zusammen, indem Sie eine Schicht Hashes dazwischen verwenden. Hier sind Diagramme für die vier Fälle:2n-1-1 × 2n-1-1.L[0]P#

    L[0]==0  L[0]==1  L[0]==2  L[0]==3
       #...  ...#     ...#...  ...#...
    [P]#...  ...#[P]  ...#...  ...#...
       #...  ...#     ...#...  ...#...
    #######  #######  #######  #######
    ...#...  ...#...     #...  ...#   
    ...#...  ...#...  [P]#...  ...#[P]
    ...#...  ...#...     #...  ...#   
    

Beispiel

Betrachten Sie die Eingabe L = [2,0]. Wir beginnen mit dem 1 × 1-Raster #und überqueren es Lvon rechts. Das am weitesten rechts stehende Element ist 0, also nehmen wir vier Kopien des 1 × 1-Gitters ., ersetzen das erste durch #und kleben sie mit Hashes zusammen. Dies ergibt das 3 × 3-Raster

##.
###
.#.

Das nächste Element ist 2 , also nehmen wir vier Kopien des 3 × 3-Gitters von .s und ersetzen das dritte durch das obige Gitter. Die vier Gitter sind

...  ...  ##.  ...
...  ...  ###  ...
...  ...  .#.  ...

und kleben sie zusammen mit # s ergibt das 7 × 7-Raster

...#...
...#...
...#...
#######
##.#...
####...
.#.#...

Dies ist unsere endgültige Ausgabe.

Eingang

Ihre Eingabe ist eine Liste Lder Indizes 0, 1, 2, 3. Sie können es als eine Liste von ganzen Zahlen oder eine Folge von Ziffern nehmen. Beachten Sie, dass es möglicherweise leer ist und Duplikate enthält. Die Länge von Lbeträgt höchstens 5.

Ausgabe

Ihre Ausgabe ist das Muster F(L)als durch Zeilenumbrüche getrennte Zeichenfolge.

Regeln und Wertung

Sie können ein vollständiges Programm oder eine Funktion schreiben. Die niedrigste Byteanzahl gewinnt, und Standardlücken sind nicht zulässig.

Testfälle

[]
#

[0]
##.
###
.#.

[3]
.#.
###
.##

[2,0]
...#...
...#...
...#...
#######
##.#...
####...
.#.#...

[1,1]
...#.##
...####
...#.#.
#######
...#...
...#...
...#...

[1,2,0]
.......#...#...
.......#...#...
.......#...#...
.......########
.......###.#...
.......#####...
.......#.#.#...
###############
.......#.......
.......#.......
.......#.......
.......#.......
.......#.......
.......#.......
.......#.......

[3,3,1]
.......#.......
.......#.......
.......#.......
.......#.......
.......#.......
.......#.......
.......#.......
###############
.......#...#...
.......#...#...
.......#...#...
.......########
.......#...#.##
.......#...####
.......#...#.#.

[0,1,2,3]
.......#...#...#...............
.......#...#...#...............
.......#...#...#...............
.......#########...............
.......#.#.#...#...............
.......#####...#...............
.......#.###...#...............
################...............
.......#.......#...............
.......#.......#...............
.......#.......#...............
.......#.......#...............
.......#.......#...............
.......#.......#...............
.......#.......#...............
###############################
...............#...............
...............#...............
...............#...............
...............#...............
...............#...............
...............#...............
...............#...............
...............#...............
...............#...............
...............#...............
...............#...............
...............#...............
...............#...............
...............#...............
...............#...............

[0,0,1,2,3]
.......#...#...#...............#...............................
.......#...#...#...............#...............................
.......#...#...#...............#...............................
.......#########...............#...............................
.......#.#.#...#...............#...............................
.......#####...#...............#...............................
.......#.###...#...............#...............................
################...............#...............................
.......#.......#...............#...............................
.......#.......#...............#...............................
.......#.......#...............#...............................
.......#.......#...............#...............................
.......#.......#...............#...............................
.......#.......#...............#...............................
.......#.......#...............#...............................
################################...............................
...............#...............#...............................
...............#...............#...............................
...............#...............#...............................
...............#...............#...............................
...............#...............#...............................
...............#...............#...............................
...............#...............#...............................
...............#...............#...............................
...............#...............#...............................
...............#...............#...............................
...............#...............#...............................
...............#...............#...............................
...............#...............#...............................
...............#...............#...............................
...............#...............#...............................
###############################################################
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
Zgarb
quelle
Warum beginnen Sie in Ihrem Beispiel mit dem 1x1-Raster #? L !=[]In diesem Beispiel hat es 1 oder mehrere Elemente. Bedeutet dies , dass F (L) ist immer eine #auf den ersten?
R. Kap
2
@ R.Kap Okay, das Beispiel ist nicht sehr klar. Die Definition ist rekursiv. L = [2,0]Sie hacken also den Kopf ab und sehen sich das Muster an F([0]). Dann hacken Sie den Kopf ab [0]und schauen sich das Muster an F([]), das das 1x1-Gitter ist #. Dann verwenden Sie den abgeschnittenen Index 0, um das 3x3-Muster zu erstellen, und den abgeschnittenen Index 2, um das 7x7-Muster zu erstellen. Um Ihre Frage zu beantworten: Ja, Sie beginnen immer mit dem 1x1-Raster, da dies der Grundfall der Rekursion ist.
Zgarb

Antworten:

6

CJam, 59 47 43 41 40 Bytes

Vielen Dank an Sp3000 für das Speichern von 1 Byte.

Sal~W%{_Bff|a4*I@t2/{zSf*z}:F%F}fI3ff+N*

Teste es hier.

Erläuterung

Etwas veraltet. Wird später behoben.

Alle Dimensionsänderungen von 4D Listen machen mich schwindelig ...

Dieser Code implementiert die Spezifikation sehr wörtlich und verwendet den iterativen Algorithmus aus dem Beispielabschnitt anstelle der rekursiven Definition. Ein wichtiger Trick beim Golfen ist, dass ich Leerzeichen anstelle #der Berechnung verwende und sie nur #am Ende durch ersetzen , was vereinfacht den Code an einer Stelle und ermöglicht es mir, Sanstelle von '#oder "#"in mehreren zu verwenden.

Sa       e# Push [" "], i.e. a 1x1 grid containing only a space as the
         e# initial fractal.
l~       e# Read and evaluate input.
W%       e# Reverse the list.
{        e# For each list element, assigning the element to variable I...
  _      e#   Duplicate the grid.
  Eff|   e#   Map (OR 14) over each character in the grid, turning spaces into
         e#   periods and leaving periods unchanged.
  a4*    e#   Create an array with four copies of this cleared grid.
  I@t    e#   Replace the Ith element in this list with the previous grid.
  2/     e#   Split this array into a 2x2 grid of subgrids...
         e#   Now it's getting a bit weird... we've got 4 dimensions now, which are:
         e#    - Rows of the 2x2 meta-grid.
         e#    - Cells in each row of the 2x2 meta-grid (i.e. subgrids).
         e#    - Rows of each subgrid.
         e#    - Characters in each row of each subgrid.
  :z     e#   Transpose each outer row, i.e. swap dimensions 2 and 3.
         e#   We've now got in each row of the meta-grid, a list of pairs of
         e#   corresponding rows of the subgrids.
  Sff*   e#   Join those pairs of rows with a single space each. We're now down
         e#   to three dimensions:
         e#    - Rows of the 2x2 meta-grid.
         e#    - Rows of each 1x2 block of the meta-grid.
         e#    - Characters in each row of those blocks.
  :z     e#   Transpose the blocks, i.e. turn the 1x2 blocks into a list of
         e#   columns of their characters.
  z      e#   Transpose the outer grid, i.e. turn it into a list of pairs of
         e#   corresponding columns in the two 1x2 blocks.
  Sf*    e#   Join each pair of columns with a single space. We've now got the
         e#   new grid we're looking for, but it's a list of columns, i.e. transposed.
  z      e#   Fix that by transposing the entire grid once more.
}I
N*       e# Join the rows of the grid with linefeeds.
S'#er    e# Replace all spaces with #.
Martin Ender
quelle
3

MATL , 42 41 Bytes

'.#'4:He!XIiP"Iq@=wX*1X@WZ(l5MY(]3Lt3$)Q)

Probieren Sie es online!

Erläuterung

Dies funktioniert iterativ mit einem Kronecker-Produkt , um das Array in jeder Iteration zu erweitern. Das Array wird mit 0und 1anstelle von .und erstellt #und am Ende durch die entsprechenden Zeichen ersetzt.

Es gibt so viele Iterationen wie die Eingabegröße. Die Eingabe wird von rechts nach links verarbeitet. Der Iterationsindex beginnt um 1.

Anhand des Beispiels in der Abfrage [2,0]wird das Array mit Eingabe wie folgt initialisiert

1 2
3 4

Dies entspricht dem initial 1( #), der um eine Zeile und eine Spalte erweitert ist, deren Zweck später klar wird. Die Werte in diesen Spalten sind nicht wichtig, da sie überschrieben werden. Sie könnten auch solche sein:

1 1
1 1

Bei jeder Iteration wird das vorhandene Array mit einem 2 × 2-Null-Eins-Array multipliziert, das 1an der durch den aktuellen Eintrag der Eingabe angegebenen Position und 0an den anderen Einträgen enthält. Im Beispiel bei der Iteration i = 1 ist 0das Null-Eins-Array , da der Eingang am weitesten rechts liegt

1 0
0 0

und das Kronecker-Produkt dieser beiden Arrays ist

 1 1 0 0
 1 1 0 0
 0 0 0 0
 0 0 0 0

Als nächstes die Zeile und Spalte mit Index 2^i mit Einsen gefüllt:

 1 1 0 0
 1 1 1 1
 0 1 0 0
 0 1 0 0

Die ersten drei Zeilen und Spalten sind das Ergebnis der ersten Iteration. Wie zuvor gibt es eine zusätzliche Zeile und Spalte, die zum Erweitern des Arrays in der nächsten Iteration nützlich sind.

Bei Iteration i = 2 2wird Kronecker-multipliziert mit , da der aktuelle Eingabewert das obige Array enthält

0 0
1 0

was gibt

 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0
 1 1 0 0 0 0 0 0
 1 1 1 1 0 0 0 0
 0 1 0 0 0 0 0 0
 0 1 0 0 0 0 0 0

Füllen Sie die 2^i-te Zeile und Spalte mit Einsen

 0 0 0 1 0 0 0 0
 0 0 0 1 0 0 0 0
 0 0 0 1 0 0 0 0
 1 1 1 1 1 1 1 1
 1 1 0 1 0 0 0 0
 1 1 1 1 0 0 0 0
 0 1 0 1 0 0 0 0
 0 1 0 1 0 0 0 0

Da dies die letzte Iteration ist, werden die zusätzliche Zeile und Spalte entfernt:

 0 0 0 1 0 0 0
 0 0 0 1 0 0 0
 0 0 0 1 0 0 0
 1 1 1 1 1 1 1
 1 1 0 1 0 0 0
 1 1 1 1 0 0 0
 0 1 0 1 0 0 0

und die Zeichensubstitution wird durchgeführt, um das Endergebnis zu erzeugen:

...#...
...#...
...#...
#######
##.#...
####...
.#.#...

Detaillierte Beschreibung des Codes folgt:

'.#'      % Push this string. Will be indexed into
4:He!     % Push 2×2 array [1 2; 3 4]
XI        % Copy it into clipboard I
iP        % Input array and reverse it
"         % For each entry of the reversed input
  I       %   Push [1 2; 3 4] from clipboard I
  q       %   Subtract 1 to yield [0 1; 2 3]
  @=      %   Compare with current entry of the input. Gives 2×2 array
          %   with an entry equal to `1` and the rest `0`
  wX*     %   Swap. Kronecker product
  1       %   Push 1
  X@      %   Push iteration index, i
  W       %   Compute 2^i
  Z(      %   Write 1 into column 2^i
  l       %   Push 1
  5M      %   Push 2^i again
  Y(      %   Write 1 into row 2^i
]         % End for each
3Lt       % Push [1, -1j] (corresponding to index 1:end-1) twice
3$)       % Apply index. Removes last row and column
Q         % Add 1. Gives an array of values 1 and 2
)         % Index into initial string
Luis Mendo
quelle
2

Haskell, 123 122 Bytes

unlines.foldr(#)["#"]
n#p=zipWith(++)(r++h:t)$('#':)<$>u++h:s where b='.'<$p<$p;h='#'<$p;(r:s:t:u:_)=drop n$cycle[p,b,b,b]

Anwendungsbeispiel:

*Main> putStr $ (unlines.foldr(#)["#"]) [2,3,1]
.......#.......
.......#.......
.......#.......
.......#.......
.......#.......
.......#.......
.......#.......
###############
...#...#.......
...#...#.......
...#...#.......
########.......
...#.###.......
...#####.......
...#.#.#.......

Wie es funktioniert:

                ["#"]      -- starting with "#" 
        foldr(#)           -- fold the function # from the right into the input
unlines                    -- and join the result with newlines

n#p=                       -- helper function #
                           -- n: next index, p: fractal so far
    zipWith(++)            -- join the left and right part elementwise
       (r++h:t)            -- left part
       ('#':) <$> u++h:s   -- right part (prepend '#' to each line for vertical
                           -- separator

                           -- helper
b='.'<$p<$p                -- b is a blank square of the same size as p
h='#'<$p                   -- h is a line of '#' of the same length as p
(r:s:t:u:_)=               -- drop the first n elements of the infinite
    drop n$cycle[p,b,b,b]  --   list [p,b,b,b,p,b,b,b,p,b,b,b,...] and
                           --   assign the next 4 element to r,s,t,u.
                           --   As r,s,t,u are always inserted at the
                           --   same position in the fractal, we get the
                           --   variants by assigning different values.
nimi
quelle
1

JavaScript (ES6), 171 152 Bytes

([d,...a],h=`#`,r=`replace`)=>d<4?(s=f(a)[r](/.+/g,s=>(t=s[r](/./g,`.`),d&1?t+h+s:s+h+t)),t=s[r](/.+/g,w=t+h+t),w=`
${w[r](/./g,h)}
`,d&2?t+w+s:s+w+t):h

Nimmt das Ergebnis des rekursiven Aufrufs und ersetzt dann jede Zeile durch sich selbst plus einen Hash plus eine Folge von Punkten gleicher Länge, falls erforderlich in umgekehrter Reihenfolge, und erstellt dann aus diesem Teilergebnis eine Folge von Punkten mit Ausnahme der Zeilenumbrüche und der mittleren Spalte Hashes und eine Reihe von Hashes mit umgebenden Zeilenumbrüchen verbinden dann diese drei Zeichenfolgen in der entsprechenden Reihenfolge.

Neil
quelle
1

Rubin, 143 134 Bytes

Eine anonyme Funktion.

1 Byte gespart durch eine Umlagerung der ersten Zeile. Durch Ändern der Art und Weise, wie z von einer Formel zu einer Tabelle inkrementiert wird, werden 6 Bytes gespart. Durch Eliminieren von varable werden 2 Bytes gespart w.

->a{r=-1+u=2<<a.size
s=(?.*r+$/)*r
a<<0
z=r*u/2-1
a.each{|i|r/=2
(-r..r).each{|j|s[z+j]=s[z+j*u]=?#}
z+=-r/2*[u+1,u-1,1-u,-u-1][i]}
s}

Ungolfed im Testprogramm

f=->a{
  r=w=(u=2<<a.size)-1        #w=length of line excluding newline, u=length of line including newline.
  s=(?.*w+$/)*w              #initialize string s with w rows of w dots terminated by newlines.
  z=w*u/2-1                  #z is the centre of the fractal
  a<<0                       #add a dummy value to the end of a
  a.each{|i|                 #for each element in a
    r/=2                     #r is the radius of the current iteration: ....15,7,3,1
    (-r..r).each{|j|         #for j=-r to r
      s[z+j]=s[z+j*u]=?#     #overwrite . with #, forming horizontal and vertical lines
    }
    z+=-r/2*(u+1)+           #move z to centre of upper left quarter (where it should be if i=0)
      i%2*(q=r+1)+           #move across if i=1,3
      i/2%2*q*u              #and down if i=2,3  
  }
s}                           #return string

puts $/,f[[]]

puts $/,f[[0]]

puts $/,f[[3]]

puts $/,f[[2,0]]

puts $/,f[[1,1]]

puts $/,f[[1,2,0]]

puts $/,f[[3,3,1]]

puts $/,f[[0,1,2,3]]

puts $/,f[[0,0,1,2,3]]
Level River St
quelle
0

Ruby, 150 Bytes

Anonyme Funktion. Verwendet einen rekursiven Aufruf, um eine Liste von Zeichenfolgen zu erstellen, eine Zeichenfolge pro Zeile, und fügt sie am Ende alle zusammen.

->i{f=->l{s=2**l.size-1;g=[[?.*s]*s]*4;m=->x,y{x.zip(y).map{|a,b|a+?#+b}}
s<1?[?#]:(g[l.shift]=f[l];m[*g[0,2]]+[?#*(2*s+1)]+m[*g[2,2]])}
f[i].join"
"}
Wert Tinte
quelle
0

Python 3.5, 1151 Bytes:

Nicht viel von einem Code Golf, aber na ja. Ich werde versuchen, es mit der Zeit zu beschneiden, wo ich kann.

def x(s):
 y=[''];l=['#'];k=[' ']
 for z in s[::-1]:y.append(z)
 y=y[::-1]
 for h in range(len(y)):
  if y[-1]!='':u=(int(y.pop())&3)
  else:u=y.pop()
  if len(l)<2:k.append(u);p=((2**(len(k)-1))-1);l.append((('.'*p+'#'+'.'*p+'\n')*p)+'#'*((p*2)+1)+'\n'+(('.'*p+'#'+'.'*p+'\n')*p))
  else:
   if len(l)>2:del l[0]
   p=((2**(len(k)-1))-1);a=[[_+i for i in range(p)]for _ in range(len(l[1]))if _%((p*2)+2)==0 and _!=(((p*2)+2)*(p))];b=[[_+i for i in range(p)]for _ in range(len(l[1]))if _%(int(((p*2)+2)/2))==0 and _!=(int(((p*2)+2)/2)*((p)*2))and _ not in[g for i in a for g in i]];W=[g for i in a[:len(a)-(int(len(a)/2)):1]for g in i];B=[g for i in b[:len(b)-(int(len(b)/2)):1]for g in i];C=[g for i in a[len(a)-(int(len(a)/2)):len(a):1]for g in i];T=[g for i in b[len(b)-(int(len(b)/2)):len(b):1]for g in i];f=list(l[1])
   for i in list(''.join(l[0].split())):
    if u==0:f[W[0]]=i;del W[0]
    elif u==1:f[B[0]]=i;del B[0]
    elif u==2:f[C[0]]=i;del C[0]
    elif u==3:f[T[0]]=i;del T[0]
   del l[0];k.append(u);p=((2**(len(k)-1))-1);l.append(''.join(f));l.append((('.'*p+'#'+'.'*p+'\n')*p)+'#'*((p*2)+1)+'\n'+(('.'*p+'#'+'.'*p+'\n')*p))
 print(l[-2])

Eine ziemlich naive Möglichkeit, dies zu tun, aber sie funktioniert derzeit einwandfrei und verwendet, wie Sie sehen, keine externen Module / Bibliotheken. Zusätzlich kann es annehmen Art und Weise mehr als 5 Artikel in der bereitgestellten Listes , ohne dass die Genauigkeit zu verlieren (das heißt, wenn Ihre Hardware kann damit umgehen). Es erfüllt alle Anforderungen und ich könnte nicht zufriedener mit dem sein, was ich habe. :)

Dank des bitweisen Operators kann jetzt auch nicht nur eine beliebige Zahl innerhalb des Bereichs 0=>3als Wert, sondern eine beliebige Zahl , Punkt, akzeptiert &werden! Sie können sie mehr über lesen hier . Nun ist zum Beispiel [4,4,1,2,3]die Eingabeliste gleich wie [0,0,1,2,3].

Hinweis: Eingabe muss als Liste bereitgestellt werden

Ungolfed mit Erklärung:

def x(s):
 # Create 3 lists:
 # `y` is for the values of `s` (the list provided) and an empty element for the 
 # first pattern
 # `l` is reserved for the pattersn created through each item in list `y`
 # `k` is created for the value of `p` which is the main value through which the 
 # pattern is created.
 y=[''];l=['#'];k=[' ']
 # Reverse s, and then add each element from `s` to `y` 
 # (in addition to the empty element) 
 for z in s[::-1]:
     y.append(z)
 # `y` should now equal the list created, but reversed
 # If not reversed, then, if, for instance, the input is `0,1,2` and list `y` 
 # therefore contains `'',2,1,0`, the empty element will be called at the end, 
 # which is NOT what we want.
 y=y[::-1]
 # The main loop; will be iterated through the length of `y` number of times
 for h in range(len(y)):
  # Here is where each element from the end of `y` is recieved as `u` for 
  # use in the pattern in each iteration.
  # As you can also see, a bitwise operator (`&`) is used here so that 
  # ALL numbers can be accepted. Not just those in the range `0-4`.     
  # However, that will happen only if the value of y[-1] (the last elment in y) is 
  # NOT ''.
  if y[-1]!='':
      u=(int(y.pop())&3)
  else:
      u=y.pop()
  # If the length of list `l` is less than 2 
  # (which means it only contains `#`), then do the following:
  if len(l)<2:
      # Append `u` to `k`
      k.append(u)
      # Use the length of `k` as `n` in the operation `(2^(n-1)-1)` to get the 
      # length of the dot filled part of the new pattern.
      p=((2**(len(k)-1))-1)
      # Add that pattern to the list (currently empty, 
      # i.e. containing no other pattern in any other quadrant)
      l.append((('.'*p+'#'+'.'*p+'\n')*p)+'#'*((p*2)+1)+'\n'+(('.'*p+'#'+'.'*p+'\n')*p))
  # Now, if the length of l is >=2, do the following:
  else:
   # If the length of l is >2, then delete the first element in list `l` 
   # (this will happen only once, when the `#` is still the first element)
   if len(l)>2:
       del l[0]
   # Again, use the length of `k` as `n` in the operation `(2^(n-1)-1)`
   # to get the length of the dot filled part of the pattern.
   p=((2**(len(k)-1))-1)
   # Create a list with all the index values of all the dot elements on the left hand 
   # side of the grid l[-1], and the index value + i where i is every integer in 
   # the range `0-p` (this way, it will create lists within a list, each 
   # which contain `p` number of integers, which are all indexes of all the dots on 
   # the very left side of the grid) 
   a=[[_+i for i in range(p)]for _ in range(len(l[1]))if _%((p
      *2)+2)==0 and _!=(((p*2)+2)*(p))]
   # Create another list with all the index values of the dots using the same 
   # strategy as above, but this time, those in the right half of the grid. 
   b=[[_+i for i in range(p)]for _ in range(len(l[1]))if _%(int(((p*2)+2)/2))==0 
      and _!=(int(((p*2)+2)/2)*((p)*2))and _ not in[g for i in a for g in i]]
   # Create 4 lists, each containing index values specific to each of the 
   # 4 quadrants of the grid.
   # W is the list, based on A, containing all the indexes for the 1st quadrant of 
   # the grid in l[-1] containing dots (index 0 in the grid)
   W=[g for i in a[:len(a)-(int(len(a)/2)):1]for g in i]
   # B is the list, this time based on b, containing all indexes for the 2nd 
   # dot-filled quadrant of the grid l[-1] (index 1 in the grid)
   B=[g for i in b[:len(b)-(int(len(b)/2)):1]for g in i]
   # C is the list, also, like W, based on a, containg all the index values for 
   # the 3rd dot-filled quadrant of the grid in l[-1] (index 2 in the grid)
   C=[g for i in a[len(a)-(int(len(a)/2)):len(a):1]for g in i]
   # T is the final list, which, also like B, is based on b, and contains all the 
   # index values for the final (4th) dot-filled quadrant of the grid in l[-1] 
   T=[g for i in b[len(b)-(int(len(b)/2)):len(b):1]for g in i];f=list(l[1])
   # Finally, in this `for` loop, utilize all the above lists to create the new 
   # pattern, using the last two elements in list `l`, where each character of grid 
   # l[-2] (the second to last element) is added to the correct index of grid l[-1] 
   # based on the value of `u`
   for i in list(''.join(l[0].split())):
    if u==0:
        f[W[0]]=i
        del W[0]
    elif u==1:
        f[B[0]]=i
        del B[0]
    elif u==2:
        f[C[0]]=i
        del C[0]
    elif u==3:
        f[T[0]]=i
        del T[0]
   # Delete the very first element of `l`, as it is now not needed anymore
   del l[0]
   # Append `u` to list`k` at the end of the loop this time
   k.append(u)
   # Update the value of `p` with the new value of length(k)
   p=((2**(len(k)-1))-1)
   # Append the new patter created from the for-loop above to list `l`
   l.append(''.join(f))
   # Append a new, empty pattern to list `l` for use in the next iteration
   l.append((('.'*p+'#'+'.'*p+'\n')*p)+'#'*((p*2)+1)+'\n'+(('.'*p+'#'+'.'*p+'\n')*p))
 # When the above main loop is all finished, print out the second-to-last elment in 
 # list `l` as the very last element is the new, empty grid created just in case 
 # there is another iteration
 print(l[-2])

Breitere und optisch ansprechendere Erklärung:

Für eine breitere und visuell ansprechendere Erklärung betrachten Sie das zweite Mal, wenn Sie die "Haupt" -Schleife im obigen Code durchlaufen, in der sich die Eingabeliste befindet [0,2]. In diesem Fall lwären die Elemente in der "Haupt" -Liste :

.#.
###
##.

und

...#...
...#...
...#...
#######
...#...
...#...
...#...

und Liste ywürde nur enthalten 0. Unter Ausnutzung von Pythons Methode zur Indizierung des letzten Elements des Gitters l[-1]können wir die ganz linken Elemente des Gitters folgendermaßen kennzeichnen:

 0 ...#...\n 7        
 8 ...#...\n 15
16 ...#...\n 23
   #######\n <- Ignore this as it is nothing but `#`s and a new line
32 ...#...\n 39
40 ...#...\n 47
48 ...#...\n 55

Welches Muster siehst du? Jeder Index ganz links im Gitter ist ein Vielfaches von 8, und da die Gleichung 2^(n-1)-1die Länge jedes Punktsegments im Gitter ergibt, können wir ((2^(n-1)-1)*2)+2die Länge der oberen Kante des Gitters als Ganzes ermitteln (+2, um das mittlere #s und das \nam Ende einzuschließen). Wir können diese Gleichung verwenden, die wir aufrufen i, um die Indexwerte jedes Elements auf der linken Seite eines Rasters beliebiger Größe zu finden, indem wir eine Liste erstellen und an die Liste jede Ganzzahl anhängen, die wir im Bereich aufrufen _werden 0=>length of grid l[-1]: so dass dieses Element ein Vielfaches von ist i, und auch so, dass _es NICHT gleich ist i*(2^(n-1)-1), so dass wir das mittlere Segment von ausschließen können#s Trennen der oberen von der unteren Hälfte. Wir wollen aber ALLE Punktelemente von links und nicht nur die Elemente ganz links. Nun, es gibt eine Lösung dafür, und das wäre, einfach an die Liste eine Liste anzuhängen, die enthält, i+hwo h jede ganze Zahl im 0=>2^(n-1)Bereich 0=>length of grid l[-1]ist, jedes Mal, wenn ein Wert aus dem Bereich zur Liste hinzugefügt wird, so dass es jedes Mal sein wird Die Anzahl der Werte, die der Liste hinzugefügt wurden, entspricht der Länge eines Quadranten von Punkten. Und das ist Listea .

Aber wie steht es jetzt mit den Punkten auf der rechten Hälfte? Schauen wir uns die Indizierung einmal anders an:

   0 ...# 4  ...\n 7        
   8 ...# 12 ...\n 15
  16 ...# 20 ...\n 23
     #######\n <- Ignore this as it is nothing but `#`s and a new line
  32 ...# 36 ...\n 39
  40 ...# 44 ...\n 47
  48 ...# 52 ...\n 55

          ^
          | 

          These are the values we are looking at now

Wie Sie sehen, sind die Werte in der Mitte diejenigen, die wir benötigen, da sie den Anfang des Index jedes Punktsegments auf der rechten Seite des Rasters darstellen. Wie ist das Muster hier? Nun, wenn es nicht schon offensichtlich genug ist, sind die Mittelwerte jetzt alle ein Vielfaches von i/2! Mit diesen Informationen können wir nun eine weitere Liste erstellen b, zu der die Vielfachen i/2aus dem Bereich hinzugefügt werden 0=>length of grid l[-1], sodass jede Ganzzahl aus dem Bereich, den wir erneut aufrufen _, NICHT gleich ist(i/2)*(p*2) , um die Zeile von auszuschließen# zwischen der oberen und der untere Hälften, UND so, dass _ NICHT bereits in Liste a enthalten ist, da wir nicht wirklich 8,16,32 usw. benötigen. in der Listeb. Und jetzt wollen wir wieder nicht nur diese spezifischen Indizes. Wir wollen ALLE Punktzeichen auf der rechten Seite des Gitters. Nun, genau wie wir es in der Liste getan ahaben, können wir hier auch der Liste hinzufügen, wo sich jede Ganzzahl im Bereich befindet .b Listen in_+hh0=>2^(n-1)

Jetzt haben wir beide Listen aund bverpackt und bereit zu gehen. Wie würden wir diese jetzt zusammenbringen? Dies ist , wo Listen W, T, G, und Ckommen in. Sie werden die Indizes auf jeden spezifischen Quadranten von Punkten in Gitter halten l[-1]. Nehmen wir zum WBeispiel die Liste als Liste für alle Indizes, die dem Quadranten 1 (Index 0) des Gitters entsprechen. In dieser Liste würden wir dann die ersten 2^(n-1)Listen aus der Liste hinzufügen a, da list aalle Indizes für Punkte in der linken Hälfte des Rasters enthält, und sie dann alle aufteilen, sodass sie Wjetzt (2^(n-1))*(2^(n-1))Elemente enthalten. Wir würden dasselbe für list tun T, jedoch mit dem Unterschied, dass TElemente aus list enthalten wärenb , daTist für Quadrant 2 (Index 1) reserviert. Liste ist Gmit Liste identisch W, enthält jedoch den Rest der Elemente aus Liste aund Liste Cist mit Liste identisch T, enthält jedoch jetzt den Rest der Elemente aus Liste b. Und das ist es! Wir haben jetzt Indexwerte für jeden Quadranten mit Punkten im Raster, die alle in vier Listen aufgeteilt sind, die jedem Quadranten entsprechen. Wir können nun diese 4 Listen (W, T, G, C) verwenden, um dem Programm mitzuteilen, welche Zeichen es im Raster l[-1]durch jedes Zeichen aus dem Raster ersetzen soll l[0], das das allererste Element der Liste ist l. Da der Wert 0hier ist, werden alle Punkte im ersten Quadranten (Index 0) durch Gitter ersetzt .l[0] Liste Rasterauslastung ersetztW

Deshalb haben wir endlich folgendes:

.#.#...
####...
##.#...
#######
...#...
...#...
...#...

Wütend! Ein langer Prozess, nicht wahr? Es funktioniert jedoch perfekt und ich könnte nicht glücklicher sein. :)

R. Kap
quelle