Art fractal carré affine ASCII

9

Écrivez le plus petit programme possible pour créer des fractales affines. Vous pouvez utiliser n'importe quelle méthode qui, selon vous, génère les mêmes résultats que les règles ci-dessous. Vous n'avez pas à utiliser les idées des méthodes suggérées!

Votre programme prendra deux entrées, la première pour définir le modèle dans le format 074composé de trois chiffres de 0 à 7. La deuxième entrée définira la taille, 3sera 8x8, 4sera 16x16 et ainsi de suite (2 ^ n). Votre programme doit produire le résultat correct pour toutes les tailles de 0 (1x1) à au moins 5 (32x32). S'il produit une sortie pour des nombres plus élevés, il doit être correct, c'est-à-dire qu'il doit produire la sortie correcte jusqu'à une certaine taille mais ne produire aucune sortie au-dessus de cette taille si elle est erronée. Vous pouvez supposer une taille maximale de 15 (32768x32768) car c'est déjà une taille folle pour l'art ASCII (1 Go)!

Un motif 8x8 ressemblera à quelque chose comme ci-dessous (règle 160). Le chiffre le plus à gauche sera pour le bloc A, le chiffre du milieu (pas de pensées grossières s'il vous plaît!) Pour le bloc Bet le chiffre le plus à droite pour le bloc C. Pour construire la fractale, réduisez-la de moitié dans les deux dimensions et appliquez la règle de rotation / symétrie pour le bloc. Pour réduire le motif, divisez-le uniformément en zones 2x2. Il y aura soit 3 caractères visibles, soit aucun dans chaque zone. S'il y a des personnages visibles, placez un personnage à l'endroit approprié dans le plus petit bloc, sinon placez un espace. Les règles 0- 3ne sont pas en miroir, les règles 4- 7sont en miroir. Les règles 0et 4ne sont pas tournés, 1et 5sont tournés de 90 degrés dans le sens horaire, 2et6sont tournés de 180 degrés 3et 7tournés de 270 degrés dans le sens des aiguilles d'une montre. Cousez les trois blocs ensemble dans l'ordre indiqué, Adans le coin supérieur gauche, en Bbas à gauche et en Cbas à droite.

 AAA    
AA A    
AA      
A       
BBB CC  
B BBC   
  BBCCC 
   B CCC

Rétréci, pivoté et mis en miroir par le numéro de règle:

 0       1       2       3       4       5       6       7  
----    ----    ----    ----    ----    ----    ----    ----
AA       BAA    CCB        C    C        BCC    AAB       AA
A       BB A     CBB      CC    CC      BBC     A BB       A
BBC     CC         A    A BB    BB A    A         CC     CBB
 BCC    C         AA    AAB      BAA    AA         C    CCB 

Règles:

  1. Pas de miroir, rotation de 90 degrés dans le sens des aiguilles d'une montre
  2. Pas de miroir, tourné de 180 degrés dans le sens des aiguilles d'une montre
  3. Pas de miroir, rotation de 270 degrés dans le sens des aiguilles d'une montre
  4. Miroir mais pas tourné
  5. Miroir puis tourné de 90 degrés dans le sens des aiguilles d'une montre
  6. Miroir puis tourné de 180 degrés dans le sens des aiguilles d'une montre
  7. Miroir puis pivoté de 270 degrés dans le sens des aiguilles d'une montre
  8. Règle 0: pas de miroir, pas de rotation

La mise en miroir est toujours effectuée en premier et se fait en diagonale dans le coin vide, par exemple, règle 0 vs règle 4:

 0       4  
----    ----
AA /    C  /
A /     CC/ 
BBC     BB A
/BCC    /BAA

Seules les règles 1, 6et 0sont utilisées dans le modèle ci-dessus, dans cet ordre. Une fois les transformations appliquées et les blocs assemblés, cela ressemblera à ce qui suit, sauf que j'ai espacé chaque bloc les uns des autres d'un espace. Votre code ne contiendra pas cet espace supplémentaire. Si vous la comparez à l'image "parent", vous verrez qu'elle a des caractères visibles dans les mêmes positions.

 BAA
BB A
CC  
C   

AAB  AA  
A BB A   
  CC BBC 
   C  BCC

Une autre façon de générer l'image sans rétrécir est la suivante: Commencez avec un caractère:

X

Appliquez les transformations pour chacun des trois blocs (aucun puisqu'il ne s'agit que d'un seul caractère) et cousez les blocs ensemble:

X
XX

Appliquez à nouveau les transformations pour chacun des trois blocs:

1 
--
XX
X 

6     0 
--    --
XX    X 
 X    XX

Assemblez-les ensemble:

XX
X 
XXX 
 XXX

Appliquez à nouveau les transformations pour chacun des trois blocs:

 1  
----
 XXX
XX X
XX  
X   

 6       0  
----    ----
XXX     XX  
X XX    X   
  XX    XXX 
   X     XXX

Assemblez-les ensemble:

 XXX    
XX X    
XX      
X       
XXX XX  
X XXX   
  XXXXX 
   X XXX

Vous pouvez utiliser n'importe quel caractère ou caractères imprimables (0x21 - 0x7E) pour la partie visible du motif, mais uniquement le caractère espace (0x20) pour les blancs. Les espaces de fin sont autorisés mais il ne doit pas y avoir de blancs à l'extérieur du carré entier (c'est-à-dire que pour un carré 8x8, il ne doit pas y avoir de caractères après la colonne 8).

Il existe 512 règles différentes, mais certaines d'entre elles produisent le même modèle. En remarque, tout motif ne contenant que 0et 4produira le triangle de Sierpinski (8 règles différentes).

Vous pouvez éventuellement publier votre modèle préféré et la règle qui le génère. Si vous le faites, assurez-vous que la taille est d'au moins 3 (8x8) pour la distinguer des règles similaires.

CJ Dennis
la source
@trichoplax Vous pouvez commencer avec un carré complètement rempli ou un carré avec seulement 1 caractère visible. Dans les deux cas, répéter les règles n fois, où n est la taille d'entrée, garantira les mêmes résultats. Cependant, vous n'avez pas besoin de générer le modèle de cette façon, mais uniquement de générer le même modèle que de le faire de cette façon.
CJ Dennis
@trichoplax J'apprécie votre contribution. La façon dont je vois les choses n'est pas nécessairement la façon dont les autres voient les choses et je ne sais pas que je leur complique la vie!
CJ Dennis
2
+1 Merci, vous avez rendu l'explication beaucoup plus claire! À l'avenir, je vous recommanderais d'exécuter les choses dans notre bac à sable afin que les gens puissent avoir une idée plus claire de ce que vous demandez à l'avance. Je travaillerai sur ce défi sous peu :)
BrainSteel
Oui, tout le monde voit les choses différemment. Heureux de donner votre avis - une bonne question mérite d'être clarifiée. Il se lit bien maintenant.
trichoplax
@BrainSteel Merci, va faire! Je suis sur SE depuis de nombreuses années mais je suis encore relativement nouveau sur PCG!
CJ Dennis

Réponses:

1

CJam, 63 57 54 52 octets

0aarari*{\f{\~7"W%z"a*3"Wf%"t<s~}({__Ser+}%\~.++}/N*

Comment ça marche :

L'idée de base est que vous exécutez une boucle, la deuxième entrée nombre de fois. Dans chaque boucle, à partir d'un seul tableau de tableau contenant 0( [[0]]), nous construisons la fractale pour l'étape suivante en utilisant les trois règles, remplissons le quadrant vide et préparons les quadrants pour la boucle suivante.

0aa                           e# Starting condition, equivalent to a single A
   ra                         e# Read the rule string and wrap it in an array
     ri*                      e# Repeat the rule array, second input number of times
        { ...  }/             e# Loop for each rule in the rule array
                              e# In each loop, we will have the current fractal and
                              e# then the rule on stack
\f{\~7"W%z"a*3"Wf%"t<s~}      
\f{                    }      e# Move the rule on top of stack and for each of the rule
                              e# character, run this loop on the current fractal
   \~                         e# Move the rule char on top and convert to int by face value
     7"W%z"a*3"Wf%"t          e# This is the array which has the logic to perform the rules
                              e# ["W%z" "W%z" "W%z" "Wf%" "W%z" "W%z" "W%z"]
                    <s        e# Based on the rule number value, take that many first items
                              e# from the above array and do a toString on the array
                              e# For rule 0 through 7, you will get the following strings:
                              e# 0: "", 1: "W%z", 2: "W%zW%z", 3: "W%zW%zW%z",
                              e# 4: "W%zW%zW%zWf%", 5: "W%zW%zW%zWf%W%z",
                              e# 6: "W%zW%zW%zWf%W%zW%z", 7: "W%zW%zW%zWf%W%zW%zW%z"
                              e# This works because each W%z will rotate the block of
                              e# fractal 90 degrees in clockwise direction.
                              e# For rule 4, where we need to mirror diagonally, we first
                              e# rotate it 279 degrees clock wise and then reverse each row
                              e# of the block. The rest of the rules after 4 take that
                              e# mirroring as base and rotate 90 degrees additionally
                      ~       e# Simply evaluate the string to apply the rule.
\f{ ... }                     e# After this for each loop, we get 3 copies of the fractal
                              e# block before the for loop. Each copy gets each one of the
                              e# three rule gets applied.
         ({      }%           e# We take out the first part corresponding to the 1st
                              e# quadrant and run each row through this loop to fill the
                              e# second quadrant with spaces
           __Ser              e# Take a copy of the row and replace everything in the
                              e# copy with spaces
                +             e# Append it to the original row
                   \~         e# Bring the last two quadrant array on top and unwrap it
                     .+       e# Append corresponding rows from the 4th quadrant to 3rd
                       +      e# Append the rows from lower half to the upper half
                              e# Now we have a full block ready to be run through
                              e# the next iteration which will double its size
                          N*  e# Finally, we join the rows of final fractal block with
                              e# newlines and automatically print the result

Essayez-le en ligne ici

Optimiseur
la source
Très belle! Il produit trop peu de caractères imprimables si le motif commence par 0et James Bond a une licence pour tuer. 007: IndexOutOfBoundsException
CJ Dennis
@CJDennis Il y a un bogue avec des zéros non significatifs. Fixé maintenant.
Optimizer
Bien joué! La sortie semble parfaite maintenant!
CJ Dennis