Sua tarefa: gerar um floco de neve Koch até a enésima profundidade. Você não precisa fazer um floco de neve Koch completo, apenas um lado do triângulo inicial. Wikipedia em flocos de Koch: https://en.wikipedia.org/wiki/Koch_snowflake .
Regras:
- O programa deve gerar um lado do floco de neve Koch até a enésima profundidade.
- A saída deve ser ASCII.
- Você pode gerar o floco de neve inteiro; isso não é necessário.
- Aplicam-se regras padrão para entrada / saída, brechas e outras coisas.
- Espaço em branco não importa, desde que todos os caracteres estejam no lugar certo em relação um ao outro.
- O código mais curto vence!
Casos de teste:
n = 0:
__
n = 1:
__/\__
n = 2:
__/\__
\ /
__/\__/ \__/\__
n = 3:
__/\__
\ /
__/\__/ \__/\__
\ /
/_ _\
\ /
__/\__ __/ \__ __/\__
\ / \ / \ /
__/\__/ \__/\__/ \__/\__/ \__/\__
Espero que isto faça sentido. Observe que em cada caso de teste, o fractal pode ser dividido em três partes iguais em comprimento. Observe também que a largura de cada floco de neve é três vezes a largura da geração anterior do floco de neve.
__/\__
com dois sublinhados, que tornaram cada iteração consistentemente três vezes maior que a anterior. Usar apenas um sublinhado parece dar contradições que começam a ficar realmente estranhas em n = 3. Por exemplo, as partes externas têm largura 12, enquanto a parte do meio tem apenas largura 10, como conseqüência/_
e_\
que são muito apertadas. E mesmo antes disso, você tem_
expandido para o dobro da largura de/
e\
./_
e_\
é a única parte realmente fatal - os sublinhados precisam desaparecer, porque precisam estar na mesma posição que o/
e\
. Uma vez feito isso, as coisas podem se expandir por 3 vezes de n = 1 em diante (mas n = 0 não se encaixa.)Respostas:
Haskell ,
308300299 bytesEditar% s:
zipWith(+)
parazipWith(-)
e ajustando codificações e deslocamentos se livrou de cada sinal de negação.#
fossem descartados usando emr=reverse
vez da correspondência direta de padrões.zipWith(-)
.o=[0,0]
para reduzir as constantes da lista.?
.Experimente online! (Infelizmente, qualquer coisa maior que n = 3 fica terrivelmente quebrada e ilegível, mas você pode copiá-lo para outro programa para vê-lo.)
Variações
[6]
para[6,4,4]
, você tem um floco de neve todo. Experimente online!,3..gcd 3x
, você obtém uma curva no estilo com o qual essa pergunta foi originalmente fornecida. Experimente online!Como funciona
k
é a função principal, pega umInt
n
e retorna aString
.iterate(>>=(:[1,4,1]))[6]
gera uma lista infinita contendo, para cada n, as voltas entre linhas consecutivas nessa iteração de curva, estilo gráfico de tartaruga, como números nominalmente entre0
e5
. Cada iteração é apenas a anterior com as curvas1,4,1
intercaladas. A única razão pela qual os sublistas começam, em6
vez de,0
é fazer ogcd
truque nof
trabalho, evitandof 0
.scanl1(+)
converte as curvas em direções "absolutas", até o módulo 6. A0
significa para a direita, então cada número mais alto é de 60 graus no sentido anti-horário do anterior. (Bem, seria 60 graus se esse fosse um desenho adequado, e não ASCII.)f
converte uma direção absoluta em uma lista de pares (caractere, codificação de deslocamento) que codifica quais caracteres adicionar à curva (para direções horizontais, gera dois pares, caso contrário um) e como a posição relativa é alterada.#
operador itera pela lista anterior de pares (caractere, codificação de deslocamento), gerando pares reais (coordenada, caractere)._/\
nominal representa uma linha desenhada de um canto inicial através de uma célula retangular para um canto final diferente.[y,x]
, de cima para baixo, da esquerda para a direita, para que sejam ordenadas na ordem em que queremos imprimi-las. As colunas são baseadas em 1. As listas são usadas em vez de tuplas para aritmética vetorial mais curta(&)=zipWith(-)
.[y,x]
que a célula no canto superior esquerdo. Isso garante que todos os deslocamentos de um canto para as células vizinhas não sejam negativos, evitando constantes negativas.[y1,x1,x2,y2]
onde[y1,x1]
está o deslocamento de coordenadas do canto inicial para a célula de caracteres e[y2,x2]
é o deslocamento do canto final para a célula de caracteres. Isso significa:3
..5
são apenas o inverso das listas para0
..2
, permitindo que elas sejam geradas com[id,r]<*>
.(&)=zipWith(-)
uma lista de codificação ou seu inverso.?
, o que gera a finalString
deles.x?l@(([_,w],c):r)
x
é a coordenada x do caractere anterior mostrado nesta linha, ou0
se no início de uma linha;l
é a lista atual inteira,w
é a coordenada x do próximo caractere a ser adicionado,c
é o caractere er
é a lista restante.\
e/
, portanto, é classificado por último se sobrepor a outro caractere na mesma posição. Assim, um sublinhado redundante é detectado verificando se uma coordenada x foi repetida.fonte