Dessinez une fractale indexée

14

introduction

Dans ce défi, une matrice 2 × 2 est indexée comme ceci:

0 1
2 3

Nous définissons une famille de modèles de type fractal F(L), où se Ltrouve une nliste de longueur de ces indices et F(L)a une taille .2n-1 × 2n-1

  • Si L == [], alors F(L)c'est le motif 1 × 1 #.
  • Si L != [], alors F(L)est construit comme suit. Soit Ple motif obtenu à partir du Lpremier élément supprimé. Prenez quatre grilles de taille remplies de points et remplacez la grille indexée par par le motif . Ensuite, collez les grilles ensemble en utilisant une couche de hachage entre elles. Voici des diagrammes pour les quatre cas: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]
    ...#...  ...#...     #...  ...#   
    

Exemple

Considérez l'entrée L = [2,0]. Nous commençons par la grille 1 × 1 #et traversons Là droite. L'élément le plus à droite est 0, nous prenons donc quatre copies de la grille 1 × 1 ., remplaçons la première par #et les collons avec des hachages. Il en résulte la grille 3 × 3

##.
###
.#.

L'élément suivant est 2, nous prenons donc quatre copies de la grille 3 × 3 de .s, et remplaçons le troisième par la grille ci-dessus. Les quatre grilles sont

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

et les coller ensemble avec #les résultats s dans la grille 7 × 7

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

Ceci est notre résultat final.

Contribution

Votre entrée est une liste Ldes indices 0, 1, 2, 3. Vous pouvez le prendre comme une liste d'entiers ou une chaîne de chiffres. Notez qu'il peut être vide et qu'il peut contenir des doublons. La longueur de Lest au plus 5.

Production

Votre sortie est le modèle F(L)sous forme de chaîne délimitée par des sauts de ligne.

Règles et notation

Vous pouvez écrire un programme complet ou une fonction. le nombre d'octets le plus bas l'emporte et les failles standard sont interdites.

Cas de test

[]
#

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

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

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

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

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

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

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

[0,0,1,2,3]
.......#...#...#...............#...............................
.......#...#...#...............#...............................
.......#...#...#...............#...............................
.......#########...............#...............................
.......#.#.#...#...............#...............................
.......#####...#...............#...............................
.......#.###...#...............#...............................
################...............#...............................
.......#.......#...............#...............................
.......#.......#...............#...............................
.......#.......#...............#...............................
.......#.......#...............#...............................
.......#.......#...............#...............................
.......#.......#...............#...............................
.......#.......#...............#...............................
################################...............................
...............#...............#...............................
...............#...............#...............................
...............#...............#...............................
...............#...............#...............................
...............#...............#...............................
...............#...............#...............................
...............#...............#...............................
...............#...............#...............................
...............#...............#...............................
...............#...............#...............................
...............#...............#...............................
...............#...............#...............................
...............#...............#...............................
...............#...............#...............................
...............#...............#...............................
###############################################################
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
...............................#...............................
Zgarb
la source
Dans votre exemple, pourquoi commencez-vous par la grille 1x1 #? L !=[]dans cet exemple, car il comporte 1 ou plusieurs éléments. Est-ce à dire que F (L) est toujours un #au début?
R. Kap
2
@ R.Kap D'accord, l'exemple n'est pas très clair. La définition est récursive, donc pour L = [2,0], vous coupez la tête et regardez le motif F([0]), puis coupez la tête [0]et regardez le motif F([]), qui est la grille 1x1 #. Ensuite, vous utilisez l'index haché 0dessus pour construire le motif 3x3, et utilisez l'index haché 2sur celui-là pour construire le motif 7x7. Pour répondre à votre question: oui, vous commencez toujours par la grille 1x1 puisque c'est le cas de base de la récursivité.
Zgarb

Réponses:

6

CJam, 59 47 43 41 40 octets

Merci à Sp3000 pour avoir économisé 1 octet.

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

Testez-le ici.

Explication

Légèrement dépassé. Fixera plus tard.

Toutes les réorganisations dimensionnelles des listes 4D me donnent le vertige ...

Ce code implémente la spécification très littéralement, en utilisant l'algorithme itératif de la section par exemple au lieu de sa définition récursive .. L' un des principaux tour du golf est que j'utilise des espaces au lieu de #pendant le calcul et ne les remplacer par #à la fin, ce qui simplifie le code en un seul endroit et me permet d'utiliser à la Splace '#ou "#"en plusieurs.

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
la source
3

MATL , 42 41 octets

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

Essayez-le en ligne!

Explication

Cela fonctionne de manière itérative à l'aide d'un produit Kronecker pour étendre la matrice à chaque itération. Le tableau est construit avec 0et 1au lieu de .et #, et à la fin, ils sont remplacés par les caractères appropriés.

Il y aura autant d'itérations que la taille d'entrée. L'entrée est traitée de droite à gauche. L'index d'itération commence à 1.

En utilisant l'exemple du défi, avec entrée [2,0], le tableau est initialisé comme

1 2
3 4

Cela correspond à l'initiale 1( #) prolongée par une ligne et une colonne, dont le but sera précisé plus tard. Les valeurs dans ces colonnes ne sont pas importantes, car elles seront écrasées; ils pourraient également être ceux:

1 1
1 1

À chaque itération, le tableau existant est multiplié par Kronecker par un tableau 2 × 2 zéro-un qui contient 1à la position indiquée par l'entrée actuelle de l'entrée et 0aux autres entrées. Dans l'exemple à l'itération i = 1, puisque l'entrée la plus à droite est 0, le tableau zéro-un est

1 0
0 0

et le produit Kronecker de ces deux tableaux est

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

Ensuite, la ligne et la colonne avec index 2^isont remplies de celles-ci:

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

Les trois premières lignes et colonnes constituent le résultat de la première itération. Comme précédemment, il existe une ligne et une colonne supplémentaires, qui sont utiles pour étendre le tableau à la prochaine itération.

À l'itération i = 2, puisque la valeur d'entrée actuelle contient 2le tableau ci-dessus est multiplié par Kronecker par

0 0
1 0

qui donne

 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

Remplir la 2^i-ème ligne et la colonne avec des unités donne

 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

Comme il s'agit de la dernière itération, la ligne et la colonne supplémentaires sont supprimées:

 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

et la substitution de caractères est effectuée pour produire le résultat final:

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

La description détaillée du code suit:

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

Haskell, 123 122 octets

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]

Exemple d'utilisation:

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

Comment ça fonctionne:

                ["#"]      -- 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
la source
1

JavaScript (ES6), 171 152 octets

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

Prend le résultat de l'appel récursif, puis remplace chaque ligne par elle-même plus un hachage plus une chaîne de points de même longueur, dans l'ordre inverse si nécessaire, puis à partir de ce résultat partiel crée une chaîne de points à l'exception des sauts de ligne et de la colonne centrale de hachages, ainsi qu'une chaîne de hachages avec des sauts de ligne environnants, puis joint ces trois chaînes ensemble dans l'ordre approprié.

Neil
la source
1

Rubis, 143 134 octets

Une fonction anonyme.

1 octet enregistré par un réarrangement de la première ligne. 6 octets enregistrés en changeant la façon dont z est incrémenté d'une formule à une table. 2 octets économisés en éliminant la variable 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 testé dans le programme de 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]]
Level River St
la source
0

Rubis, 150 octets

Fonction anonyme. Utilise un appel récursif pour construire une liste de chaînes, une chaîne par ligne, puis les joint toutes ensemble à la fin.

->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"
"}
Encre de valeur
la source
0

Python 3.5, 1151 octets:

Pas beaucoup de golf de code, mais bon. J'essaierai de l'élaguer plus au fil du temps où je peux.

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

Une façon assez naïve de le faire, mais, néanmoins, fonctionne actuellement parfaitement et, comme vous pouvez le voir, n'utilise aucun module / bibliothèque externe. En outre, il peut prendre manière plus de 5 articles dans la liste fournie ssans perdre la précision (qui est, si votre matériel peut manipuler). Il répond à toutes les exigences et je ne pourrais pas être plus satisfait de ce que j'ai obtenu. :)

Il peut désormais non seulement accepter n'importe quel nombre dans la plage 0=>3comme n'importe quelle valeur, mais n'importe quel nombre , point, grâce à l' &opérateur au niveau du bit! Vous pouvez en savoir plus à leur sujet ici . Maintenant, par exemple, [4,4,1,2,3]comme la liste d'entrée est la même que [0,0,1,2,3].

Remarque: L' entrée doit être fournie sous forme de liste

Non golfé avec explication:

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

Explication plus large et beaucoup plus attrayante visuellement:

Pour une explication plus large et beaucoup plus attrayante visuellement, considérez la deuxième fois en passant par la boucle "principale" dans le code ci-dessus, dans laquelle se trouve la liste d'entrée [0,2]. Dans ce cas, les éléments de la liste "principale" lseraient:

.#.
###
##.

et

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

et la liste yne contiendrait que 0. Profitant de la façon dont Python indexe le dernier élément de la grille l[-1], nous pouvons étiqueter les éléments très à gauche de la grille comme suit:

 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

Quel modèle voyez-vous? Chaque index à l'extrême gauche de la grille est un multiple de 8, et puisque, en utilisant l'équation 2^(n-1)-1donne la longueur de chaque segment de points dans la grille, nous pouvons faire ((2^(n-1)-1)*2)+2pour trouver la longueur du bord supérieur de la grille dans son ensemble (+2 pour inclure le milieu #et \nle fin). Nous pouvons utiliser cette équation, que nous appellerons ipour trouver les valeurs d'index de chaque élément sur le côté gauche d'une grille de n'importe quelle taille en créant une liste, et en ajoutant à la liste chaque entier, que nous appellerons _, dans la plage 0=>length of grid l[-1], de telle sorte que cet élément soit un multiple de i, ET également tel qu'il _N'EST PAS égal i*(2^(n-1)-1), afin que nous puissions exclure le segment central de#s séparant la moitié supérieure de la moitié inférieure. Mais nous voulons TOUS les éléments dot de la gauche, et pas seulement les éléments tout à gauche. Eh bien, il y a un correctif à cela, et ce serait d'ajouter simplement à la liste une liste contenant i+hoù h est chaque entier de la plage 0=>2^(n-1)chaque fois qu'une valeur de la plage 0=>length of grid l[-1]est ajoutée à la liste, de sorte qu'à chaque fois, il y aura autant de valeurs ajoutées à la liste que la longueur d'un quadrant de points. Et c'est la liste a.

Mais maintenant, que diriez-vous des points sur la moitié droite? Eh bien, regardons l'indexation d'une manière différente:

   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

Comme vous pouvez le voir, les valeurs maintenant au milieu sont celles dont nous avons besoin, car elles sont le début de l'index de chaque segment de points sur le côté droit de la grille. Maintenant, quel est le modèle ici? Eh bien, si ce n'est pas déjà assez évident, maintenant les valeurs moyennes sont toutes des multiples de i/2! Avec ces informations, nous pouvons maintenant créer une autre liste b, à laquelle les multiples de i/2sont ajoutés à partir de la plage0=>length of grid l[-1] sorte que chaque entier de cette plage, que nous appellerons à nouveau _, n'est PAS égal à (i/2)*(p*2)pour exclure la ligne de #s séparant le haut et moitiés inférieures, ET tel que _ ne soit PAS déjà dans la liste a, car nous n'avons pas vraiment besoin de 8,16,32, etc. dans la listeb. Et maintenant, encore une fois, nous ne voulons pas seulement ces index spécifiques. Nous voulons TOUS les points sur le côté droit de la grille. Eh bien, tout comme nous l'avons fait dans la liste a, ici, nous pouvons également ajouter à la liste des blistes _+hoù se htrouve chaque entier de la plage 0=>2^(n-1).

Maintenant, nous avons les deux listes aet bemballés et prêts à l'emploi. Comment pourrions-nous les réunir maintenant? C'est là listes W, T, Get Centrent en jeu . Ils détiendront les index pour chaque quadrant spécifique de points dans la grille l[-1]. Par exemple, réservons la liste Wcomme liste pour tous les index égaux au quadrant 1 (index 0) de la grille. Dans cette liste, nous ajouterions ensuite les premières 2^(n-1)listes de list a, car list acontient tous les index des points dans la moitié gauche de la grille, puis les diviser tous afin qu'ils Wcontiennent maintenant des (2^(n-1))*(2^(n-1))éléments. Nous ferions de même pour la liste T, mais avec la différenceT contiendrait des éléments de la liste b, carTest réservé pour le quadrant 2 (index 1). La liste Gserait la même que la liste W, sauf qu'elle contiendrait le reste des éléments de la liste a, et la liste Cest la même que la liste T, sauf qu'elle contient maintenant le reste des éléments de la liste b. Et c'est tout! Nous avons maintenant des valeurs d'index pour chaque quadrant contenant des points dans la grille, tous divisés en quatre listes correspondant à chaque quadrant. Nous pouvons maintenant utiliser ces 4 listes (W, T, G, C) pour indiquer au programme quels caractères il doit remplacer dans la grille l[-1]par chaque caractère de la grille l[0], qui est le tout premier élément de la liste l. Puisque la valeur est 0ici, elle remplacerait tous les points du premier quadrant (index 0) par une grille l[0]utilisant la listeW.

Par conséquent, nous avons enfin les éléments suivants:

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

Ouf! Un long processus, n'est-ce pas? Cependant, cela fonctionne parfaitement et, encore une fois, je ne pourrais pas être plus heureux. :)

R. Kap
la source