Frattali affini quadrati di arte ASCII


9

Scrivi il programma più piccolo possibile per creare frattali affini. Puoi usare qualsiasi metodo che ritieni generi gli stessi risultati delle regole seguenti. Non devi usare alcuna idea dai metodi suggeriti!

Il tuo programma prenderà due input, il primo per definire il modello nel formato 074composto da tre cifre da 0 a 7. Il secondo input definirà la dimensione, 3sarà 8x8, 4sarà 16x16 e così via (2 ^ n). Il tuo programma deve produrre il risultato corretto per tutte le dimensioni da 0 (1x1) ad almeno 5 (32x32). Se produce un output per numeri più alti, deve essere corretto, ovvero deve produrre l'output corretto fino a una determinata dimensione ma non produrre alcun output oltre tale dimensione se sarebbe sbagliato. Puoi assumere una dimensione massima di 15 (32768x32768) in quanto è già una dimensione folle per l'arte ASCII (1 GB)!

Un modello 8x8 sarà simile al seguente (regola 160). La cifra più a sinistra sarà per il blocco A, la cifra centrale (per favore niente pensieri maleducati!) Per il blocco Be la cifra più a destra per il blocco C. Per costruire il frattale, ridurlo di mezzo in entrambe le dimensioni e applicare la regola di rotazione / mirroring per il blocco. Per ridurre il motivo, dividerlo uniformemente in aree 2x2. Ci saranno 3 caratteri visibili o nessuno in ogni area. Se ci sono personaggi visibili, posiziona un personaggio nella posizione appropriata nel blocco più piccolo, altrimenti posiziona uno spazio. Le regole 0- 3non sono speculari, le regole 4- 7sono speculari. Regole 0e 4non sono ruotati, 1e 5vengono ruotati di 90 gradi in senso orario, 2e6sono ruotati di 180 gradi 3e 7ruotati di 270 gradi in senso orario. Cuci i tre blocchi insieme nell'ordine mostrato, Anell'angolo in alto a sinistra, in Bbasso a sinistra e in Cbasso a destra.

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

Ridotto, ruotato e rispecchiato dal numero di regola:

 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 

Regole:

  1. Non specchiato, ruotato di 90 gradi in senso orario
  2. Non specchiato, ruotato di 180 gradi in senso orario
  3. Non specchiato, ruotato di 270 gradi in senso orario
  4. Specchiato ma non ruotato
  5. Specchiato, quindi ruotato di 90 gradi in senso orario
  6. Specchiato, quindi ruotato di 180 gradi in senso orario
  7. Specchiato, quindi ruotato di 270 gradi in senso orario
  8. Regola 0: non speculare, non ruotato

Il mirroring viene sempre eseguito per primo e viene eseguito in diagonale attraverso l'angolo vuoto, ad es. Regola 0 vs regola 4:

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

Solo regole 1, 6e 0sono utilizzati nel modello di cui sopra, in questo ordine. Dopo che le trasformazioni sono state applicate e i blocchi sono stati cuciti insieme, sembrerà il seguente, tranne per il fatto che ho distanziato ciascun blocco l'uno dall'altro di uno spazio. Il tuo codice non avrà questo spazio extra al suo interno. Se lo confronti con l'immagine "principale", vedrai che ha caratteri visibili nelle stesse posizioni.

 BAA
BB A
CC  
C   

AAB  AA  
A BB A   
  CC BBC 
   C  BCC

Un altro modo per generare l'immagine senza ridurla è il seguente: Inizia con un carattere:

X

Applica le trasformazioni per ciascuno dei tre blocchi (nessuno poiché è solo un carattere) e unisci i blocchi:

X
XX

Applicare nuovamente le trasformazioni per ciascuno dei tre blocchi:

1 
--
XX
X 

6     0 
--    --
XX    X 
 X    XX

Ricucili insieme:

XX
X 
XXX 
 XXX

Applicare nuovamente le trasformazioni per ciascuno dei tre blocchi:

 1  
----
 XXX
XX X
XX  
X   

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

Ricucili insieme:

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

È possibile utilizzare qualsiasi carattere o caratteri stampabili (0x21 - 0x7E) per la parte visibile del motivo, ma solo il carattere spazio (0x20) per gli spazi vuoti. Gli spazi finali sono consentiti ma non devono essere presenti spazi esterni all'intero quadrato (ovvero per un quadrato 8x8 non possono essere presenti caratteri oltre la colonna 8).

Esistono 512 regole diverse, ma alcune producono lo stesso modello. Come nota a margine, qualsiasi modello contenente solo 0e 4produrrà il triangolo Sierpinski (8 regole diverse).

Puoi opzionalmente pubblicare il tuo modello preferito e la regola che lo genera. In tal caso, assicurati che la dimensione sia almeno 3 (8x8) per distinguerla da regole simili.


@trichoplax Puoi iniziare con un quadrato completamente pieno o un quadrato con solo 1 carattere visibile al suo interno. In entrambi i casi, ripetere le regole n volte, dove n è la dimensione di input, garantirà gli stessi risultati. Tuttavia, non è necessario generare il modello in questo modo, generare solo lo stesso modello di farlo in questo modo.
CJ Dennis,

@trichoplax Apprezzo il tuo contributo. Il modo in cui vedo le cose non è necessariamente il modo in cui le altre persone vedono le cose e non so che le sto rendendo difficili!
CJ Dennis,

2
+1 Grazie, hai reso la spiegazione molto più chiara! In futuro, ti consiglierei di gestire le cose attraverso la nostra sandbox in modo che le persone possano avere un'immagine più chiara di ciò che stai chiedendo in anticipo.
Lavorerò

Sì, tutti vedono le cose diversamente. Felice di dare un feedback: vale la pena chiarire una buona domanda. Ora legge bene.
trichoplax,

@BrainSteel Grazie, lo farà! Sono stato su SE per molti anni ma sono ancora relativamente nuovo su PCG!
CJ Dennis,

Risposte:


1

CJam, 63 57 54 52 byte

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

Come funziona :

L'idea di base è che si esegue un ciclo, il secondo numero di input di volte. In ogni ciclo, partendo da un singolo array di array contenente 0( [[0]]), costruiamo il frattale per il passaggio successivo usando le tre regole, riempiamo il quadrante vuoto e prepariamo i quadranti per il ciclo successivo.

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

Provalo online qui


Molto bello! Produce troppi caratteri stampabili se il modello inizia 0e James Bond ha una licenza per uccidere. 007: IndexOutOfBoundsException
CJ Dennis,

@CJDennis È presente un bug con zeri iniziali. Riparato ora.
Ottimizzatore,

Molto bene! L'output ora sembra perfetto!
CJ Dennis,

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.