Gere uma espiral ASCII Padovan

22

Esta é a versão ASCII deste desafio . A postagem inicial foi separada por solicitação por Martin Ender

Introdução

Semelhante à Sequência de Fibonacci, a Sequência Padovan ( OEIS A000931 ) é uma sequência de números produzida pela adição de termos anteriores na sequência. Os valores iniciais são definidos como:

P(0) = P(1) = P(2) = 1

Os 0º, 1º e 2º termos são todos 1. A relação de recorrência é declarada abaixo:

P(n) = P(n - 2) + P(n - 3)

Assim, produz a seguinte sequência:

1, 1, 1, 2, 2, 3, 4, 5, 7, 9, 12, 16, 21, 28, 37, 49, 65, 86, 114, 151, 200, 265, 351, ...

Usar esses números como comprimentos laterais de triângulos equilaterais produz uma espiral agradável quando você os junta, como a Espiral de Fibonacci:

insira a descrição da imagem aqui

Imagem cortesia da Wikipedia


Tarefa

Sua tarefa é escrever um programa que recria essa espiral pela arte ASCII, com entrada correspondente a qual termo. Como um triângulo de comprimento lateral 1 (1 caractere) é impossível de representar bem em ASCII, os comprimentos laterais foram dilatados por um fator de 2. Portanto, o triângulo de comprimento lateral 1 é realmente representado da seguinte forma:

 /\
/__\

Portanto, por exemplo, se a entrada foi 5 (o quinto termo), a saída deve ser:

   /\
  /  \
 /    \
/______\
\      /\
 \    /__\ 
  \  /\  /
   \/__\/

Os 5 primeiros termos foram 1, 1, 1, 2, 2, então o triângulo tinha comprimentos laterais 2, 2, 2, 4, 4 devido à dilatação. Outro exemplo para a entrada 8:

     __________
   /\          /\
  /  \        /  \
 /    \      /    \
/______\    /      \
\      /\  /        \
 \    /__\/          \
  \  /\  /            \
   \/__\/______________\
    \                  /
     \                /
      \              /
       \            /
        \          /
         \        /
          \      /
           \    /
            \  /
             \/

Regras

  • Você deve imprimir o resultado e a entrada deve ser um número inteiro correspondente ao número do termo
  • Novas linhas à direita e à direita são permitidas, espaços à direita depois das linhas também
  • Seu envio deve ser capaz de lidar com pelo menos até o 10º período (9)
  • Seu envio deve ser um programa ou função completo que receba informações e imprima o resultado
  • As rotações da saída são permitidas, em múltiplos de 60 graus, mas o tamanho dos triângulos deve permanecer o mesmo, junto com a representação
  • Também é permitido ir no sentido anti-horário
  • As brechas padrão são proibidas

Você pode assumir que a entrada será> 0 e que o formato correto da entrada será fornecido.

Pontuação

Isso é , então o código mais curto em bytes vence. Feliz ano novo a todos!

Andrew Li
fonte
1
meu idioma Turtlèd pode receber entrada da base 10 e processá-la bem, mas esse desafio seria muito mais fácil se a entrada fosse unária. isso seria permitido?
Destrutível Lemon
1
@DestructibleWatermelon Sim. A entrada apenas precisa ser inteira, de alguma forma.
Andrew Li
legal. Vou começar a trabalhar agora #
Destructible Lemon
3
espere, na verdade, ainda é muito difícil
Destructible Lemon

Respostas:

13

Befunge, 871 836 798 bytes

&00p45*:10p20p030p240p050p060p9010gp9110gp1910gp1-91+10gpv
<v-g03+g06*2g041g055_v#!:%6:p06p05+p04g05g06:g04<p*54+292<
->10g:1\g3+:70p110gv >:5- #v_550g:01-\2*40g+1-30g
/\110:\-g03:\1:g055 _v#!-4:<vp01:-1g01-g03-1\-
^1<v07+1:g07< p08p < >:1-#v_550g:01-\40g+60g+1-30g-50g>v
 _0>p80gp:5-|v1\+66\:p\0\9:$<:p02:+1g02-g03+g06-\g04\1:<
0v|-g00:+1$$<>\p907^>p:!7v>3-#v_550g:30g+:30p1\0\-
1>10g+::0\g3-:70p\0^^07<v<>50#<g::30g+:30p-1-01-\
v >\$0gg> :1+10gg1- #v_^>0g10gg*+\:!2*-70g2+10gv>:#->#,"_"$#1_:1#<p
+1+g03$_^#`gg011+3:+3<g07\+*2+*`0:-\gg01+5g07:g<>1#,-#*:#8>#4_$#:^#
>55+,p30g40p10gg10g1>#v_
#v:#p0$#8_:$#<g!#@_0^ >
 >>:180gg`>>#|_:2+80gg:!v
3+^g\0p08:<vgg08+2::+3<$_100p1-v>g,\80gg+\80gp:2+90g:!01p\80gp
!#^_80g:1+^>\180gg`+!#^_20g80g`
5*g10!g09p04-1-\0\+g04:gg08:p09<^3`0:gg08+1:::$$_1#!-#\\:,#\<g

Experimente online!

Como costuma acontecer com o Befunge, o truque é criar um algoritmo que nos permita renderizar o padrão de cima para baixo, já que não é possível transformá-lo na memória primeiro com o espaço limitado disponível.

A maneira como isso funciona é primeiro construindo uma estrutura de dados simples, representando as arestas necessárias para desenhar a espiral. O segundo estágio analisa essa estrutura de cima para baixo, renderizando os fragmentos de borda necessários para cada linha de saída.

Usando essa técnica, podemos suportar até n = 15 na implementação de referência antes de começarmos a ter problema de estouro nas células de memória de 8 bits. Intérpretes com um tamanho de célula maior devem poder suportar até n = 25 antes de ficar sem memória.

James Holderness
fonte
isso é muito impressionante ... mas você acha que consegue ler esses programas? lol para mim, parece tão aleatório. como ele constrói a estrutura de dados? que tipo de estrutura de dados ele usa? obrigado!
don brilhante
1

vai, 768 bytes

func 卷(n int){
    数:=0
    p:=[]int{1,1,1}
    for i:=3;i<n;i++ {p=append(p,p[i-2]+p[i-3])}
    宽:=p[len(p)-1]*10+10
    素:=make([]int,宽*宽)
    for 数=range 素 {素[数]=32}
    for i:=0;i<数;i+=宽 {素[i]=10}
    态:=[]int{1,1,宽/2,宽/2,92}
    表:=[70]int{}
    s:="SRSQTSPQQ!QOQP~QQQQQQSQR~ORQR!OPOPTSQRQ$QPPQNQPPPXQQQQQQRRQXQRRRNOQPQ$"
    for i:=range s {表[i]=int(s[i])-33-48}
    表[49],表[59]=48,48
    for i:=0;i<4*n;i++ {
        梴:=p[i/4]*2
        if 态[1]==0 {梴=梴*2-2}
        for k:=0;k<梴;k++ {
            址:=(态[2]+态[3]*宽)%len(素)
            if 素[址]==32 {素[址]=态[4]}
            态[2]+=态[0]
            态[3]+=态[1]
        }
        数=((态[0]+1)*2+态[1]+1)*5
        if i%4>2 {数+=35}
        for k:=0;k<5;k++ {态[k]+=表[数+k]}
    }
    for i:=0;i<宽*宽;i++ {fmt.Printf("%c",rune(素[i]))}
}

Obviamente, isso não é ideal, mas não é um começo ruim. Eu sei que é provavelmente um pouco simples para os padrões de golfe, mas foi divertido e espero que não se importe se eu deixar algumas notas para o futuro.

Como funciona

Basicamente, simulo uma 'tartaruga de desenho', como no LOGO, em uma grade de pixels ASCII, mas a tartaruga só pode executar estes três comandos:

rt   - right turn, turn 120 degrees right (1/3 of a Turn)
rth  - right turn half, turn  60 degrees right (1/6 of a Turn)
fd n - forward, go forward n steps, drawing a trail of _, /, or \

Agora, para cada triângulo, eu vou assim, onde P é 2x o enésimo número de Padovan:

fd P
rt
fd P
rt 
fd P
rt
fd P
rth

O quarto 'fd' significa que estou re-traçando o primeiro lado de cada triângulo. Isso ajuda a voltar a um bom ponto de partida para o próximo triângulo. A meia curva à direita garante que o próximo triângulo esteja na orientação correta.


Para jogar golfe na tartaruga, guardo 5 variáveis ​​de estado na matriz 态: posição x, posição y, velocidade x, velocidade y e 'desenho da runa'. Em cada quadro de animação, x + = x velocidade, y + = y velocidade, e a runa é desenhada.

Então eu montei a tabela 表 que diz como realmente executar o turno. O código do turn é complicado devido à maneira como a arte ASCII funciona. Não é um movimento direto, como em uma exibição de pixels. A direção da tartaruga, determinada pelas velocidades xey, determina as mudanças necessárias para que a curva pareça adequada.

Para girar, ele analisa a velocidade xey atual e as combina em um índice.

xv = x velocity, yv = y velocity. 
i.e. a turtle facing down and to the right has 
xv of 1, and yv of 1. It can only face 6 
different directions. Formula is (xv+1)*2+yv+1

xv  yv    index
-1  -1    0
-1   0    1
-1   1    2
 1  -1    4
 1   0    5
 1   1    6

Este índice é usado para pesquisar um conjunto de 5 valores na tabela 表. Esses 5 valores na tabela 表 são adicionados a cada uma das 5 variáveis ​​no estado 态. A tartaruga é então efetivamente virada e pronta para o próximo 'fd'.

Em seguida, meia volta à direita, há uma seção separada da tabela.. É compensado pelas entradas 7 * 5 ou 35 da primeira tabela em 表.

Por fim, fiz uma codificação simples dos números inteiros da tabela em uma string ascii.

Eu sei que eu poderia 'salvar bytes' removendo o Hanzi, mas como eu disse, isso não é ideal e há mais possibilidades de golfe ... Eu as removerei quando não houver outra otimização possível. Na verdade, esses Hanzi têm um significado vagamente baseado em seu significado real, e mesmo que eu não saiba chinês, isso me ajuda a pensar no programa.

数  index number
宽  screen width
素  pixel data
梴  length of side of triangle
态  current state
址  address of pixel
表  state transition table

Para testar o código, você precisará do arquivo golang completo, com este cabeçalho

package main
import "fmt"

e este rodapé

func main ()  {
    for i := 0; i<15; i++ {
       卷(i)
    }
}

obrigado

não brilhante
fonte