Disegna un frattale indicizzato


14

introduzione

In questa sfida, una matrice 2 × 2 viene indicizzata in questo modo:

0 1
2 3

Definiamo una famiglia di modelli frattali F(L), in cui Lè presente un nelenco di F(L)lunghezza di questi indici e ha dimensioni .2n-1 × 2n-1

  • Se L == [], allora F(L)è il modello 1 × 1 #.
  • Se L != [], allora F(L)è costruito come segue. Sia Pil modello ottenuto Lcon il primo elemento rimosso. Prendi quattro griglie di dimensioni riempite con punti e sostituisci la griglia indicizzata da con il motivo . Quindi, incolla le griglie insieme usando uno strato di hash tra di loro. Ecco i diagrammi per i quattro casi: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]
    ...#...  ...#...     #...  ...#   
    

Esempio

Considera l'input L = [2,0]. Iniziamo con la griglia 1 × 1 #e attraversiamo Lda destra. L'elemento più a destra è 0, quindi prendiamo quattro copie della griglia 1 × 1 ., sostituiamo la prima con #e le incolliamo insieme con gli hash. Ciò si traduce nella griglia 3 × 3

##.
###
.#.

L'elemento successivo è 2, quindi prendiamo quattro copie della griglia 3 × 3 di .s e sostituiamo la terza con la griglia sopra. Le quattro griglie sono

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

e incollandoli insieme ai #risultati di s nella griglia 7 × 7

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

Questo è il nostro risultato finale.

Ingresso

Il tuo input è un elenco Ldi indici 0, 1, 2, 3. Puoi prenderlo come un elenco di numeri interi o una stringa di cifre. Si noti che può essere vuoto e può contenere duplicati. La lunghezza di Lè al massimo 5.

Produzione

L'output è il modello F(L)come stringa delimitata da nuova riga.

Regole e punteggio

È possibile scrivere un programma completo o una funzione. vince il conteggio di byte più basso e non sono consentite scappatoie standard.

Casi test

[]
#

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

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

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

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

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

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

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

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

Nel tuo esempio, perché inizi con la griglia 1x1 #? L !=[]in questo esempio, poiché ha 1 o più elementi. Questo significa che F (L) è sempre un #in un primo momento?
R. Kap

2
@ R.Kap Va bene, l'esempio non è molto chiaro. La definizione è ricorsiva, quindi per L = [2,0], tagliare la testa e guardare il modello F([0]), quindi tagliare la testa di [0]e guardare il modello F([]), che è la griglia 1x1 #. Quindi si utilizza l'indice troncato 0su di esso per costruire il modello 3x3 e si utilizza l'indice troncato 2su quello per costruire il modello 7x7. Per rispondere alla tua domanda: sì, inizi sempre con la griglia 1x1 poiché questo è il caso base della ricorsione.
Zgarb,

Risposte:


6

CJam, 59 47 43 41 40 byte

Grazie a Sp3000 per il salvataggio di 1 byte.

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

Provalo qui.

Spiegazione

Leggermente obsoleto. Risolverà più tardi.

Tutti i riordini dimensionali delle liste 4D mi fanno girare la testa ...

Questo codice implementa le specifiche in modo molto letterale, usando l'algoritmo iterativo dalla sezione di esempio invece della sua definizione ricorsiva. Un trucco di golf importante è che sto usando gli spazi anziché #durante il calcolo e li sostituisco solo con #alla fine, il che semplifica il codice in un posto e mi permette di usare al Sposto di '#o "#"in diversi.

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 #.

3

MATL , 42 41 byte

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

Provalo online!

Spiegazione

Funziona in modo iterativo usando un prodotto Kronecker per estendere l'array in ogni iterazione. L'array è costruito con 0e 1invece di .e #, e alla fine sono sostituiti dai caratteri appropriati.

Ci saranno tante iterazioni quante le dimensioni dell'input. L'input viene elaborato da destra a sinistra. L'indice di iterazione inizia alle 1.

Usando l'esempio nella sfida, con input [2,0], l'array viene inizializzato come

1 2
3 4

Ciò corrisponde all'iniziale 1( #) esteso di una riga e una colonna, il cui scopo sarà chiarito in seguito. I valori in quelle colonne non sono importanti, poiché saranno sovrascritti; potrebbero ugualmente essere quelli:

1 1
1 1

Ad ogni iterazione, l'array esistente viene moltiplicato per Kronecker per un array zero-one 2 × 2 che contiene 1nella posizione indicata dalla voce corrente dell'input e 0nelle altre voci. Nell'esempio all'iterazione i = 1, poiché la voce di input più a destra è 0, l'array zero-one è

1 0
0 0

e il prodotto Kronecker di questi due array è

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

Successivamente, la riga e la colonna con indice 2^ivengono riempite con quelle:

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

Le prime tre righe e colonne costituiscono il risultato della prima iterazione. Come in precedenza, sono presenti una riga e una colonna aggiuntive, utili per estendere l'array nella successiva iterazione.

All'iterazione i = 2, poiché l'attuale valore di input contiene 2l'array sopra è Kronecker moltiplicato per

0 0
1 0

che dà

 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

Riempiendo la 2^iriga e colonna con quelli da

 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

Poiché questa è l'ultima iterazione, la riga e la colonna aggiuntive vengono rimosse:

 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

e la sostituzione del personaggio viene effettuata per produrre il risultato finale:

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

Segue una descrizione dettagliata del codice:

'.#'      % 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

2

Haskell, 123 122 byte

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]

Esempio di utilizzo:

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

Come funziona:

                ["#"]      -- 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.

1

JavaScript (ES6), 171 152 byte

([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

Prende il risultato della chiamata ricorsiva, quindi sostituisce ogni riga con se stessa più un hash più una stringa di punti della stessa lunghezza, in ordine inverso se necessario, quindi da quel risultato parziale crea una stringa di punti ad eccezione delle newline e della colonna centrale di hash e anche una stringa di hash con le nuove linee circostanti, quindi unisce le tre stringhe nell'ordine appropriato.


1

Rubino, 143 134 byte

Una funzione anonima.

1 byte salvato da un riarrangiamento della prima riga. 6 byte salvati modificando il modo in cui z viene incrementato da una formula a una tabella. 2 byte salvati eliminando la variabile 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}

Non registrato nel programma di test

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

0

Rubino, 150 byte

Funzione anonima. Utilizza una chiamata ricorsiva per creare un elenco di stringhe, una stringa per riga, quindi le unisce tutte alla fine.

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

0

Python 3.5, 1151 byte:

Non molto di un codice golf, ma vabbè. Cercherò di potarlo più nel tempo dove posso.

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

Un modo abbastanza ingenuo per farlo, ma, tuttavia, attualmente funziona perfettamente e, come puoi vedere, non utilizza moduli / librerie esterne. Inoltre, si può prendere il via più di 5 elementi nell'elenco fornito ssenza perdere la precisione (che è, se il vostro hardware in grado di gestirlo). Soddisfa tutti i requisiti e non potrei essere più felice di quello che ho ottenuto. :)

Ora può anche accettare non solo un numero compreso nell'intervallo 0=>3come uno qualsiasi dei valori, ma qualsiasi numero , punto, grazie &all'operatore bit a bit! Puoi leggere di più su di loro qui . Ora, ad esempio, [4,4,1,2,3]poiché l'elenco di input è lo stesso di [0,0,1,2,3].

Nota: l' ingresso deve essere fornito come un elenco

Ungolfed con spiegazione:

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

Spiegazione più ampia e visivamente più accattivante:

Per una spiegazione più ampia e visivamente più accattivante, si consideri la seconda volta passando attraverso il "main" -loop nel codice sopra, in cui si trova l'elenco di input [0,2]. In questo caso, gli elementi nell'elenco "principale" lsarebbero:

.#.
###
##.

e

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

e l'elenco yconterrà solo 0. Sfruttando il modo di Python di indicizzare l'ultimo elemento della griglia l[-1], possiamo etichettare gli elementi della griglia molto a sinistra in questo modo:

 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

Che modello vedi? Ogni indice all'estrema sinistra della griglia è un multiplo di 8 e poiché, usando l'equazione, si 2^(n-1)-1ottiene la lunghezza di ogni segmento di punti nella griglia, possiamo fare ((2^(n-1)-1)*2)+2per trovare la lunghezza del bordo superiore della griglia nel suo insieme (+2 per includere le #s centrali e \nalla fine). Possiamo usare quell'equazione, che chiameremo iper trovare i valori dell'indice di ciascun elemento sul lato sinistro di una griglia di qualsiasi dimensione creando un elenco e accodando all'elenco ogni numero intero, che chiameremo _, nell'intervallo 0=>length of grid l[-1], tale che quell'elemento è un multiplo di i, E anche tale che _NON è ugualei*(2^(n-1)-1) , in modo che possiamo escludere il segmento centrale di#s che separa la metà superiore dalla metà inferiore. Ma vogliamo TUTTI gli elementi punto da sinistra, e non solo gli elementi sul lato sinistro. Bene, c'è una soluzione a questo, e sarebbe semplicemente aggiungere alla lista un elenco contenente i+hdove h è ogni numero intero nell'intervallo 0=>2^(n-1)ogni volta che un valore dall'intervallo 0=>length of grid l[-1]viene aggiunto all'elenco, in modo che ogni volta ci sarà altrettante quantità di valori aggiunti all'elenco quanti sono la lunghezza di un quadrante di punti. E questa è la lista a.

Ma ora, che ne dici dei punti sulla metà destra? Bene, diamo un'occhiata all'indicizzazione in un modo diverso:

   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

Come puoi vedere, i valori ora nel mezzo sono quelli di cui abbiamo bisogno, in quanto sono l' inizio dell'indice di ogni segmento di punti sul lato destro della griglia. Ora, qual è lo schema qui? Bene, se non è già abbastanza ovvio, ora i valori medi sono tutti multipli di i/2! Con queste informazioni, ora possiamo creare un altro elenco, ba cui i multipli di i/2vengono aggiunti dall'intervallo in modo 0=>length of grid l[-1]tale che ogni intero da quell'intervallo, che chiameremo di nuovo _, NON sia uguale (i/2)*(p*2)a escludere la linea di #s che separa la parte superiore e metà inferiori, E tale che _ NON sia già nell'elenco a, poiché non abbiamo davvero bisogno di 8,16,32, ecc. in elencob. E ora, di nuovo, non vogliamo solo quegli indici specifici. Vogliamo TUTTI i caratteri punto sul lato destro della griglia. Bene, proprio come abbiamo fatto nella lista a, qui possiamo anche aggiungere alla lista bliste di _+hdove hè ogni numero intero nell'intervallo 0=>2^(n-1).

Ora, abbiamo entrambe le liste ae bconfezionati e pronti ad andare. Come li riuniremmo ora? Questo è dove le liste W, T, G, e Csono disponibili in. Si terrà gli indici per ogni specifico quadrante di punti nella griglia l[-1]. Ad esempio, cerchiamo di riservare l'elenco Wcome elenco per tutti gli indici pari al quadrante 1 (indice 0) della griglia. In questo elenco, aggiungeremmo quindi i primi 2^(n-1)elenchi dall'elenco a, poiché l'elenco acontiene tutti gli indici per i punti nella metà sinistra della griglia, quindi li divideremo tutti in modo che Wora contenga (2^(n-1))*(2^(n-1))elementi. Faremo lo stesso per la lista T, ma con la differenza che Tconterrebbe elementi dalla listab , da alloraTè riservato per il quadrante 2 (indice 1). L'elenco Gsarebbe uguale all'elenco W, ad eccezione del fatto che conterrebbe il resto degli elementi dell'elenco ae l'elenco Cè uguale all'elenco T, tranne per il fatto che ora contiene il resto degli elementi dall'elenco b. E questo è tutto! Ora disponiamo di valori di indice per ogni quadrante contenente punti nella griglia, tutti suddivisi in quattro elenchi corrispondenti a ciascun quadrante. Ora possiamo usare queste 4 liste (W, T, G, C) per dire al programma quali caratteri dovrebbe sostituire in griglia l[-1]con ogni carattere della griglia l[0], che è il primo elemento dell'elenco l. Poiché il valore è 0qui, sostituirà tutti i punti nel primo quadrante (indice 0) con l[0]l'elenco di utilizzo della grigliaW.

Pertanto, finalmente abbiamo il seguente:

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

Meno male! Processo lungo, no? Tuttavia, funziona perfettamente e, ancora una volta, non potrei essere più felice. :)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.