Sua tarefa para hoje: desenhe uma curva de dragão!
Caso você não saiba o que é uma curva do dragão, aqui está um vídeo introdutório do ViHart (muito legal, por favor, assista!)
Sua tarefa: desenhe uma curva de dragão, iterada pelo menos 9 vezes. Você não precisa mostrar as iterações de 1 a 9, apenas a curva final produzida após concluir (pelo menos) 9 iterações. A curva deve ser desenhada como linhas retas conectando os pontos na curva; a saída deve corresponder a uma das imagens abaixo que mostra 9 ou mais iterações (até reflexão, rotação, escala e variação na largura da linha, cor da linha e cor do plano de fundo). Sua saída deve ser grande o suficiente para que as linhas individuais e as "caixas" que elas formam possam ser distinguidas uma da outra; se duas linhas não se cruzam na curva, elas não devem ocupar os mesmos pixels ou pixels adjacentes na saída (deve haver pelo menos um pixel do plano de fundo visível entre elas). Você pode exibir a imagem na tela ou salvar a imagem em um arquivo. A saída deve ser gráfica - não pode ser arte ASCII.
O código mais curto em bytes ganha, no entanto , as diretivas para bibliotecas não devem ser incluídas na contagem de bytes, e você pode usar bibliotecas gráficas ou outras bibliotecas escritas para o idioma de sua escolha se elas foram escritas antes da publicação.
Por favor, inclua uma imagem da saída do seu programa.
Pule este parágrafo se você assistiu ao vídeo:Para aqueles que decidiram não assistir ao vídeo, as 12 primeiras iterações da curva do dragão são mostradas abaixo. Para os fins desta tarefa, uma curva de dragão é uma curva gerada pela seguinte regra: pegue o ponto final da curva atual, crie uma segunda curva girada 90 graus em torno desse ponto final, para que o ponto final do original curva é o ponto inicial da nova curva e une as duas curvas em uma única curva onde elas se encontram. Nas imagens mostradas abaixo, cada nova iteração é gerada girando a iteração anterior 90 graus no sentido horário em torno do ponto final de cada iteração. Quando a curva é exibida na tela, não é óbvio qual extremidade conta como o "ponto final"; no entanto, quando a curva é armazenada como uma matriz de pontos, é fácil definir o "ponto final" como o último ponto em a matriz.
Ascii art é apreciada, mas não aceita: Esta é uma saída gráfica, não ascii-art.
fonte
Respostas:
x86, MSDOS, 16 bytes
Escrevi isso há um tempo atrás, até onde sei, a menor rotina para produzir um fractal de dragão. Ele não usa iterações reais, mas plota todos os pixels discretos contidos diretamente no fractal, mostrando a imagem final . Está incluído em muitas outras pequenas produções neste pacote . A versão de 16 bytes foi o fim do meu esforço para obter o fractal do dragão o menor possível, a partir de 2014 com esta produção de 32 bytes .
Hex
Código
fonte
Python 2/3,
1691671501119878 bytesObserve que a importação não está incluída na contagem de bytes, de acordo com as especificações do desafio.
Agradecemos a @AlexHall por salvar 39 (!) Bytes e a @ nedla2004 por mais 13
Começa gerando uma lista ou gire à direita (90) e à esquerda (-90), depois percorre a lista e move a tartaruga.
Saída gerada:
EDIT: Se isso é muito chato demais assistir, adicione
speed(0)
logo antes do primeirofd(5)
. Funcionará da mesma forma, exceto que a tartaruga se moverá muito mais rápido.fonte
Logotipo, 43 bytes
Tente com o intérprete em http://www.calormen.com/jslogo/#
Isso usa o mesmo princípio que minha resposta de arte ASCII anterior e a fórmula na wikipedia, exceto que eu invertei a direção para corresponder à imagem na pergunta:
bitand :i -:i
encontra o bit menos significativo dei
. Dividimosi
por isso shitfti
direito a quantidade necessária, dando ao número ímpar necessáriok
. Não há necessidade de distinguir entre curvas à esquerda e à direita; nós apenas vire à esquerda pork*90
graus e confiamos no fato de que a rotação é uma operação do módulo 360 para executar o módulo para nós.Resultado
usar
ht
para esconder a tartaruga, se necessário.Saída (modificada)
A seguir, mostramos como a curva é um único fio.
fonte
LindenMASM , 51 Bytes
O LindenMASM foi um idioma que eu criei para um desafio há algum tempo e que viverá para sempre na Sandbox. Utiliza o conceito de sistemas Lindenmayer para desenhar coisas como curvas de dragão, plantas fractais, triângulos de Sierpinski, etc.
O código fonte é o seguinte:
Para configurar isso,
n = 6
por exemplo:Isso produz a seguinte imagem via Python 3
turtle
:Pode haver uma pequena diferença de numeração para as iterações, pois no sistema Lindenmayer a primeira iteração é uma única linha. Aqui está o que parece
n = 10
:Apenas por diversão, aqui está a aparência de 15 gerações (com instruções adicionais
MOV 2
para torná-lo um pouco menor):Depois de chegar a 20 gerações (com
MOV 0.5
), você não consegue mais ver as linhas, e são necessárias muitas etapas para criar (pares de pares+-
e-+
não são otimizados). Aqui está o que você recebe:Observe que o intérprete atual pode apresentar problemas gráficos por pequenas quantidades de gerações, ou seja, possivelmente não atraindo a tela. Infelizmente, quando esse intérprete foi criado, não houve problemas, uma possível alteração no Python 3 poderia ter causado isso ou poderia ser apenas o meu sistema
fonte
Subcarga, 196 bytes
Eu pensei que poderia ser interessante tentar esse desafio em um esolang de baixa potência; O Underload se sai bem em um idioma com um número tão baixo de comandos.
A saída é um arquivo SVG com tags muito aninhadas e alguns atalhos de golfe. Até agora, não encontrei um navegador que possa exibi-lo (o Firefox trava por vários minutos tentando carregá-lo, e o Firefox e o Chromium exibem uma tela em branco). A maioria dos programas de processamento de imagens também não pode carregá-lo (dificultando a conversão para outro formato), mas consegui carregá-lo no visualizador de imagens Eye of Gnome (que faz parte da instalação padrão no Ubuntu). Então, tirei uma captura de tela da imagem para que você possa vê-la (a imagem real tem um plano de fundo transparente, mas você não pode capturar uma tela transparente):
Precisamos especificar o tamanho da imagem explicitamente. Escolher uma orientação apropriada para a imagem, desenhar tudo no tamanho mínimo legal e fazer o número mínimo de iterações especificadas pelo desafio, nos dá uma imagem que cabe apenas em 99 pixels de largura, economizando um byte. É bom quando as coisas funcionam assim.
O algoritmo geral usado para desenhar a imagem é manter duas variáveis (não subcarga não nomear variáveis, mas eu pensei neles como x e y ), ambos inicialmente vazio. Em seguida, substituímos repetidamente ( x , y ) por ( x , vire à esquerda e avance, y ) e ( x , vire à direita e avance, y ). Após dez iterações, x e y mantêm uma curva de dragão de nove iterações.
Também existem algumas micro-otimizações e truques específicos para o Underload. A fim de evitar o excesso de brincar com o topo da pilha, cada iteração do loop, começamos combinando x e y para a função "retornar a string criado pela concatenação: x , uma instrução por sua vez, o argumento da função, um movi- instrução para a frente e y ". Essa função ocupa apenas um espaço na pilha, para que possamos duplicá-la, chamá-la
-90
como argumento, trocar o valor de retorno pela duplicata e chamá-la90
como argumento para obter novos valores para x e ysem precisar tocar mais do que os dois principais elementos da pilha (que são de longe os mais acessíveis). Esta função é gerada por código em tempo de execução. O gerador em si também é gerado por código em tempo de execução, para permitir a reutilização da string<g transform="translate
que também é usada para definir a origem da imagem. Primeiro, geramos todas as tags abertas e, em seguida, porque todas as tags de fechamento são justas</g>
, podemos produzir 1024 tags de fechamento simplesmente repetindo a string, sem nos preocupar em correspondê-las às tags abertas. (Escrever números eficientemente em Underload é um problema interessante por si só;(:*)::*:**:*
provavelmente é a maneira mais eficiente de escrever 1024, traduzindo "2 para a potência de (1 + 2 × 2) × 2").O Underload não possui bibliotecas gráficas, por isso produzo SVG usando uma combinação de linhas de desenho em uma posição fixa e girando a imagem em torno de um determinado ponto; em vez de girar a caneta, giramos o papel. A idéia é que, desenhando uma linha, girando a imagem inteira, desenhando outra linha, girando a imagem novamente etc., podemos simular efetivamente gráficos de tartarugas sem ter que fazer nenhuma aritmética ou usar bibliotecas de gráficos, pois todas as linhas são desenhadas no mesmo local. Obviamente, isso significa que temos algumas tags de rotação da imagem muito aninhadas, o que confunde muitos visualizadores SVG.
O estilo da imagem contaria contra a contagem de bytes, portanto, eu precisava fornecer o estilo mínimo necessário para exibir a imagem. Isso acaba sendo
stroke="#"
, que mais ou menos se traduz como "a linha precisa ter alguma cor"; isso parece ser expandido para desenhá-lo em preto. (Normalmente, você especificaria a cor como, por exemplo, "# 000".) O plano de fundo é transparente por padrão. Não especificamos uma largura de traçado, mas a escolha escolhida pelo Olho do Gnomo deixa tudo visível.Muitos intérpretes do Underload lutam com esse programa, por exemplo, o do Try It Online falha, porque gera algumas seqüências muito grandes internamente. O intérprete online Underload original funciona, no entanto. (Interessante, o primeiro intérprete estava on-line, portanto o idioma era utilizável on-line antes de ser usado off-line.)
Algo que me incomoda um pouco é que parece haver apenas 1023 segmentos de linha aqui, e esperamos 1024. Pode ser que um dos segmentos no final não esteja sendo desenhado com esse algoritmo (seria desenhada na próxima iteração). Se isso é desqualificante, pode ser possível adaptar o programa, mas pode acabar bem mais longo. (Não é como se esse desafio vencesse a competição de qualquer maneira; já existem várias inscrições mais curtas.)
fonte
MATL , 26 bytes
Se diferentes escalas nos dois eixos forem aceitas, o código poderá ser reduzido para 19 bytes:
As figuras abaixo correspondem à versão em escala igual (26 bytes).
O código acima produz a 9a-iteração (com base em 0), ou seja, a décima imagem no desafio:
Para outros valores, altere o
9
código ou substitua-o pori
para obter o número como entrada do usuário. Por exemplo, o resultado para13
é:Explicação
Isso usa um loop para construir gradualmente uma matriz das etapas seguidas pela curva no plano complexo. Por exemplo, os dois primeiros passos são
1j
(para cima) e-1
(para a esquerda).Em cada iteração, a matriz de etapas até agora é copiada. A cópia da matriz é revertida , multiplicada por
1j
(para girar 90 graus) e concatenada ao original.Após o loop, uma soma acumulada das etapas fornece os pontos reais, que são plotados no plano complexo.
fonte
Mathematica 86 bytes
Como funciona:
{1,-1}
Saídas{1,-1}
. Basicamente "empurra para a pilha". Este valor pode ser recuperado com%
.r=Reverse
basicamente apenas renomeia a função Reverse porque eu a uso duas vezes no código. OGraphics@Line@
apenas pega uma lista de pontos e desenha uma linha conectando-os. A carne real do problema acontece neste segmento de código:Nest[Join[l=Last@#;h=#-l&/@#,r[r@#%&/@h]]&,{{0,0},%},9]
. Deixa eu te contar - esse segmento é complicado pra caralho. Aqui está o queNest
faz:Nest[f,x,9]
gera o resultado da chamadaf[f[f[f[f[f[f[f[f[x]]]]]]]]]
.No meu código, esse primeiro argumento
f
é :,Join[l=Last@#;h=#-l&/@#,r[r@#%&/@h]]&
o segundo argumentox
é{{0,0},%}
(que é avaliado como{{0,0},{1,-1}}
) e o terceiro argumento én
, que é apenas 9 (que apenas aplicará o primeiro argumento ao segundo argumento 9 vezes).A parte mais complexa de tudo é esse primeiro argumento:,
Join[l=Last@#;h=#-l&/@#,r[r@#%&/@h]]&
que é uma bagunça gigante de açúcar sintático quase puro. Eu estava realmente abusando do açúcar sintático do mathematica por este. Essa linha de código representa a versão do mathematica de uma função anônima, exceto para encurtar as coisas que realmente defini duas funções anônimas separadas dentro dessa função anônima. Sim, isso é legal, pessoal. Vamos dividir.Join
leva dois argumentos. O primeiro él=Last@#;h=#-l&/@#
e o segundo ér[r@#%&/@h]
.O primeiro argumento de Join: Dentro da função anônima "principal",
#
é uma lista de todos os pontos da iteração atual na curva. Entãol=Last@#;
significa "Pegue o ponto na lista de pontos que você recebeu como entrada e atribua esse ponto à variávell
. O próximo segmento,,h=#-l&/@#
é um pouco mais complexo. Significa" Você tem uma função. Essa função pega um ponto como entrada, subtrail
e retorna o resultado. Agora, aplique essa função a todos os elementos da lista de pontos que você recebeu como entrada para gerar uma lista de pontos deslocados e atribua essa nova lista à variávelh
.O segundo argumento de Join:
r[r@#%&/@h]
tem literalmente a sintaxe mais complexa que já escrevi. Não acredito que qualquer segmento de código possa conter algo como@#%&/@
- parece que estou xingando como um personagem de desenho animado no meio de um programa! Mas é possível decompô-lo. Lembrar -r[x]
pega uma lista de pontos e retorna essa lista em ordem inversa.r@#%&
é uma função anônima que inverte sua entrada e a multiplica pelo valor armazenado em%
(que é{1,-1}
) e retorna o resultado. Basicamente, ele gira sua entrada em 90 graus, mas no código o mais curto que eu poderia escrever. Entãor@#%&/@h
significa "Crie uma nova lista com todos os pontosh
girados em 90 graus".Tão geral,
Join[l=Last@#;h=#-l&/@#,r[r@#*%&/@h]]&
é uma função que pega uma lista de pontos como entrada e adiciona a mesma lista de pontos girados 90 graus para obter a próxima iteração da curva. Isso é repetido 9 vezes para obter a curva do dragão. Em seguida, a lista de pontos resultante é desenhada na tela como uma linha. E a saída:fonte
0{,}
... funciona porque0 x
é0
para quase todox
e{,}
é açúcar sintático para{Null,Null}
.Python 2, 43 bytes
Esta resposta tem 43 bytes, sem incluir a declaração de importação, e é amplamente baseada na resposta do logotipo da Level River St e seu uso
i/(i&-i)
no código. Experimente online em trinket.ioAqui está uma imagem da saída.
fonte
The shortest code in bytes wins, however include directives for libraries shouldn't be included in the byte count, and you may use graphics libraries or other libraries written for your language of choice if they were written before the posting.
Mathematica,
5655 bytesExplicação: OEIS A034947
Apenas por diversão, aqui está uma versão colorida da 19a iteração.
fonte
Mathematica, 63 bytes
Usando
AnglePath
fonte
HTML + JavaScript, 182
fonte
Haskell + diagramas, 179 bytes
A saída é um arquivo svg de 99 pixels de largura e fundo transparente (uma imagem de 9 pixels de largura teria um traçado muito espesso para recuperar qualquer coisa). Aqui é redimensionado e composto sobre um fundo branco:
fonte
tosh , 518 bytes
tosh é zero , mas com texto em vez de blocos. Com 518 bytes, essa resposta é provavelmente ainda pior que Java.
Esta resposta usa a mesma lógica que a resposta Python de @ Theo , mas com seqüências de caracteres de "L" e "R" em vez de números, pois os recursos da lista de Scratch (e, portanto, de Tosh) são terríveis.
Você pode executá-lo como um projeto do zero aqui . (tosh compila em projetos do Scratch)
Explicação:
Esta primeira parte faz com que o programa seja executado quando a bandeira verde é clicada (
when flag clicked
), define a variável do caminho como "R" e coloca o sprite e o estágio no estado adequado para estar pronto para desenhar.Agora chegamos ao código de geração de caminho. Ele usa a mesma lógica da resposta Python de @ Theo , exceto com as seqüências de caracteres de "R" e "L" em vez de números, e usamos loops aninhados em vez de compreensão de lista.
Por fim, desenhamos o caminho percorrendo cada letra da variável do caminho e girando para a esquerda ou direita, dependendo da letra.
fonte