Fractais afins quadrados de arte ASCII

9

Escreva o menor programa possível para criar fractais afins. Você pode usar qualquer método que achar que gere os mesmos resultados que as regras abaixo. Você não precisa usar nenhuma idéia dos métodos sugeridos!

Seu programa terá duas entradas, a primeira a definir o padrão no formato 074de três dígitos de 0 a 7. A segunda entrada definirá o tamanho, 3será 8x8, 4será 16x16 e assim por diante (2 ^ n). Seu programa deve gerar o resultado correto para todos os tamanhos, de 0 (1x1) a pelo menos 5 (32x32). Se produzir qualquer saída para números mais altos, deve estar correta, ou seja, deve produzir a saída correta até um determinado tamanho, mas não produzirá saída acima desse tamanho, se estiver errado. Você pode assumir um tamanho máximo de 15 (32768x32768), já que esse é um tamanho insano para a arte ASCII (1 GB)!

Um padrão 8x8 será semelhante a abaixo (regra 160). O dígito mais à esquerda será para o bloco A, o dígito do meio (sem pensamentos rudes, por favor!) Para o bloco Be o dígito mais à direita para o bloco C. Para construir o fractal, reduza-o pela metade em ambas as dimensões e aplique a regra de rotação / espelhamento para o bloco. Para reduzir o padrão, divida-o igualmente em áreas 2x2. Haverá 3 caracteres visíveis ou nenhum em cada área. Se houver caracteres visíveis, coloque um caractere no local apropriado no bloco menor, caso contrário, coloque um espaço. Regras 0- 3não são espelhadas, regras 4- 7são espelhadas. Regras 0e 4não são rotacionadas, 1e 5são giradas 90 graus no sentido horário, 2e6são girados 180 graus 3e 7girados 270 graus no sentido horário. Costure os três blocos juntos na ordem mostrada, Ano canto superior esquerdo, no canto Binferior esquerdo e no Ccanto inferior direito.

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

Encolhido, girado e espelhado pelo número da regra:

 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 

Regras:

  1. Não espelhado, girado 90 graus no sentido horário
  2. Não espelhado, girado 180 graus no sentido horário
  3. Não espelhado, girado 270 graus no sentido horário
  4. Espelhado, mas não girado
  5. Espelhado e girado 90 graus no sentido horário
  6. Espelhado e girado 180 graus no sentido horário
  7. Espelhado e girado 270 graus no sentido horário
  8. Regra 0: Não espelhado, Não girado

O espelhamento é sempre feito primeiro e é feito diagonalmente no canto em branco, por exemplo, regra 0 vs regra 4:

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

Apenas regras 1, 6e 0são usados no padrão acima, nessa ordem. Após as transformações terem sido aplicadas e os blocos costurados, eles se parecerão com os abaixo, exceto que espaçei cada bloco um do outro por um espaço. Seu código não terá esse espaço extra. Se você compará-lo com a imagem "pai", verá que ele possui caracteres visíveis nas mesmas posições.

 BAA
BB A
CC  
C   

AAB  AA  
A BB A   
  CC BBC 
   C  BCC

Outra maneira de gerar a imagem sem diminuir é a seguinte: Comece com um caractere:

X

Aplique as transformações para cada um dos três blocos (nenhum, pois é apenas um caractere) e costure os blocos:

X
XX

Aplique as transformações para cada um dos três blocos novamente:

1 
--
XX
X 

6     0 
--    --
XX    X 
 X    XX

Costure-os juntos:

XX
X 
XXX 
 XXX

Aplique as transformações para cada um dos três blocos novamente:

 1  
----
 XXX
XX X
XX  
X   

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

Costure-os juntos:

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

Você pode usar qualquer caractere ou caracteres imprimíveis (0x21 - 0x7E) para a parte visível do padrão, mas apenas o caractere de espaço (0x20) para os espaços em branco. Espaços finais são permitidos, mas não deve haver espaços em branco fora do quadrado inteiro (por exemplo, para um quadrado 8x8, não pode haver caracteres após a coluna 8).

Existem 512 regras diferentes, mas algumas produzem o mesmo padrão. Como observação lateral, qualquer padrão que contenha apenas 0e 4produzirá o triângulo de Sierpinski (8 regras diferentes).

Opcionalmente, você pode postar seu padrão favorito e a regra que o gera. Se o fizer, verifique se o tamanho é pelo menos 3 (8x8) para diferenciá-lo de regras semelhantes.

CJ Dennis
fonte
@trichoplax Você pode começar com um quadrado completamente preenchido ou um quadrado com apenas 1 caractere visível. De qualquer forma, repetir as regras n vezes, em que n é o tamanho da entrada, garantirá os mesmos resultados. No entanto, você não precisa gerar o padrão dessa maneira, apenas gerar o mesmo padrão que fazê-lo dessa maneira.
CJ Dennis
@trichoplax Agradeço sua opinião. A maneira como vejo as coisas não é necessariamente a maneira como as outras pessoas veem as coisas e não sei se estou dificultando para elas!
CJ Dennis
2
+1 Obrigado, você tornou a explicação muito mais clara! No futuro, eu recomendaria que você publicasse nossa caixa de areia para que as pessoas pudessem ter uma ideia mais clara do que você está pedindo com antecedência. Eu vou estar trabalhando neste desafio logo :)
BrainSteel
Sim, todo mundo vê as coisas de maneira diferente. É um prazer dar feedback - vale a pena esclarecer uma boa pergunta. Lê bem agora.
Trichoplax #
@BrainSteel Obrigado, vai fazer! Estou no SE há muitos anos, mas ainda sou relativamente novo no PCG!
CJ Dennis

Respostas:

1

CJam, 63 57 54 52 bytes

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

Como funciona :

A idéia básica é que você execute um loop, o segundo número de entrada de vezes. Em cada loop, a partir de uma única matriz de array contendo 0( [[0]]), construímos o fractal para a próxima etapa usando as três regras, preenchemos o quadrante vazio e preparamos os quadrantes para o próximo loop.

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

Experimente online aqui

Optimizer
fonte
Muito bonito! Produz poucos caracteres imprimíveis se o padrão começar 0e James Bond tiver uma licença para matar. 007: IndexOutOfBoundsException
CJ Dennis
@CJDennis Há um erro nos zeros à esquerda. Corrigido agora.
Optimizer
Bem feito! A saída parece perfeita agora!
CJ Dennis
0

APL (Dyalog Classic) , 47 bytes

⊃(⊂⍪⍕#){,/⍪⌿↑1 ¯2↑¨⊂⍺{⍉∘⊖⍣⍺⌽⍉⍣(⍺>3)⌽⍵}¨⍵}⍣⎕⍨⍎¨⍞

Experimente online!

ngn
fonte