Generar una espiral de Padovan ASCII

22

Esta es la versión ASCII de este desafío . La publicación inicial fue separada por solicitud por Martin Ender

Introducción

Similar a la secuencia de Fibonacci, la secuencia de Padovan ( OEIS A000931 ) es una secuencia de números que se produce al agregar términos anteriores en la secuencia. Los valores iniciales se definen como:

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

Los términos 0º, 1º y 2º son todos 1. La relación de recurrencia se establece a continuación:

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

Por lo tanto, produce la siguiente secuencia:

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

El uso de estos números como longitudes laterales de triángulos equiláteros produce una espiral agradable cuando los coloca todos juntos, al igual que la espiral de Fibonacci:

ingrese la descripción de la imagen aquí

Imagen cortesía de Wikipedia.


Tarea

Su tarea es escribir un programa que recrea esta espiral mediante el arte ASCII, con la entrada correspondiente a qué término. Dado que un triángulo de longitud lateral 1 (1 carácter) es imposible de representar muy bien en ASCII, las longitudes laterales se han dilatado por un factor de 2. Por lo tanto, el triángulo de longitud lateral 1 se representa realmente así:

 /\
/__\

Entonces, por ejemplo, si la entrada fue 5 (el quinto término), la salida debería ser:

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

Los primeros 5 términos fueron 1, 1, 1, 2, 2, por lo que el triángulo tenía longitudes laterales 2, 2, 2, 4, 4 debido a la dilatación. Otro ejemplo para la entrada 8:

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

Reglas

  • Debe imprimir el resultado, y la entrada debe ser un número entero correspondiente al número de término
  • Se permiten líneas nuevas y finales nuevas, también se permiten espacios finales después de las líneas
  • Su envío debe ser capaz de manejar al menos hasta el décimo término (9)
  • Su envío debe ser un programa completo o una función que tome datos e imprima el resultado
  • Se permiten rotaciones de la salida, en múltiplos de 60 grados, pero el tamaño de los triángulos debe permanecer igual, junto con la representación
  • Ir en sentido antihorario también está permitido
  • Las lagunas estándar están prohibidas

Puede suponer que la entrada será> 0 y que se dará el formato correcto de entrada.

Tanteo

Este es el , por lo que gana el código más corto en bytes. ¡Feliz Año Nuevo a todos!

Andrew Li
fuente
1
Mi idioma Turtlèd puede tomar la entrada de base 10 y procesarla bien, pero este desafío sería mucho más fácil si tomara la entrada como unaria. ¿eso estaría permitido?
Destructible Lemon
1
@DestructibleWatermelon Sí. La entrada solo tiene que ser entera, en algún tipo de forma.
Andrew Li el
guay. Comenzaré a trabajar en ello ahora
Destructible Lemon
3
espera en realidad todavía es muy difícil
Destructible Lemon

Respuestas:

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

Pruébalo en línea!

Como suele ser el caso con Befunge, el truco está surgiendo con un algoritmo que nos permite renderizar el patrón de arriba a abajo, ya que no es posible renderizarlo primero en la memoria con el espacio limitado disponible.

La forma en que esto funciona es primero creando una estructura de datos simple que represente los bordes necesarios para dibujar la espiral. La segunda etapa analiza esa estructura de arriba a abajo, mostrando los fragmentos de borde necesarios para cada línea de salida.

Con esta técnica, podemos admitir hasta n = 15 en la implementación de referencia antes de comenzar a tener problemas de desbordamiento en las celdas de memoria de 8 bits. Los intérpretes con un tamaño de celda mayor deberían poder admitir hasta n = 25 antes de quedarse sin memoria.

James Holderness
fuente
eso es muy impresionante ... pero ¿crees que puedes leer estos programas? jajaja para mí se ve tan al azar. ¿Cómo construye la estructura de datos? ¿Qué tipo de estructura de datos utiliza? ¡Gracias!
Don brillante
1

ir, 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]))}
}

Por supuesto, esto no es óptimo, pero no es un mal comienzo. Sé que probablemente sea un poco simple para los estándares de golf, pero fue divertido y espero que no le importe si dejo algunas notas para el futuro.

Cómo funciona

Básicamente simulo una 'tortuga de dibujo' como en LOGO en una cuadrícula de píxeles ASCII, pero la tortuga solo puede hacer estos tres 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 \

Ahora para cada triángulo, voy así, donde P es 2 veces el enésimo número de Padovan:

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

El cuarto 'fd' significa que estoy volviendo a trazar el primer lado de cada triángulo. Esto ayuda a volver a un buen punto de partida para el próximo triángulo. La media vuelta a la derecha asegura que el próximo triángulo estará en la orientación adecuada.


Para jugar golf a la tortuga, almaceno 5 variables de estado en la matriz 态: posición x, posición y, velocidad x, velocidad y y 'runa de dibujo'. En cada cuadro de animación, x + = velocidad x, y + = velocidad y, y se dibuja la runa.

Luego configuré la tabla 表 que dice cómo realizar el turno. El código de giro es complicado debido a la forma en que funciona el arte ASCII. No es un movimiento directo como en una pantalla de píxeles. La dirección de la tortuga, determinada por la velocidad xey, determina los cambios necesarios para que el giro se vea bien.

Para girar, observa la velocidad actual de x e y, y las combina en un í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 se utiliza para buscar un conjunto de 5 valores en la tabla 表. Esos 5 valores en la tabla 表 luego se agregan a cada una de las 5 variables en el estado 态. La tortuga se gira efectivamente y está lista para el próximo 'fd'.

Para rth, la mitad del giro a la derecha, hay una sección separada de la tabla 表. Está compensado por 7 * 5, o 35, entradas de la primera tabla en 表.

Por último, hice una codificación simple de los enteros de la tabla en una cadena ascii.

Sé que podría 'guardar bytes' eliminando el Hanzi, pero como dije, esto no es óptimo y hay más golf posible ... Los eliminaré cuando no haya otra optimización posible. Esos Hanzi en realidad tienen un significado vago basado en su significado real, y aunque no sé chino, me ayuda a pensar en el programa.

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

Para probar el código, necesitará un archivo golang completo, con este encabezado

package main
import "fmt"

y este pie de página

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

Gracias

don brillante
fuente