Genera una spirale padovana ASCII


22

Questa è la versione ASCII di questa sfida . Il post iniziale è stato separato per richiesta da Martin Ender

introduzione

Simile alla sequenza di Fibonacci, la sequenza di Padovan ( OEIS A000931 ) è una sequenza di numeri che viene prodotta aggiungendo termini precedenti nella sequenza. I valori iniziali sono definiti come:

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

I termini 0, 1 e 2 sono tutti 1. La relazione di ricorrenza è indicata di seguito:

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

Pertanto, produce la seguente sequenza:

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

L'uso di questi numeri come lunghezze laterali dei triangoli equilateri produce una bella spirale quando li metti tutti insieme, proprio come la spirale di Fibonacci:

inserisci qui la descrizione dell'immagine

Immagine gentilmente concessa da Wikipedia


Compito

Il tuo compito è quello di scrivere un programma che ricrea questa spirale con l'arte ASCII, con input corrispondente a quale termine. Poiché un triangolo di lunghezza laterale 1 (1 carattere) è impossibile da rappresentare bene in ASCII, le lunghezze laterali sono state dilatate di un fattore 2. Pertanto, il triangolo di lunghezza laterale 1 è effettivamente rappresentato in questo modo:

 /\
/__\

Quindi, ad esempio, se l'input era 5 (il 5 ° termine), l'output dovrebbe essere:

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

I primi 5 termini erano 1, 1, 1, 2, 2, quindi il triangolo aveva lunghezze laterali 2, 2, 2, 4, 4 a causa della dilatazione. Un altro esempio per l'ingresso 8:

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

Regole

  • È necessario stampare il risultato e l'input deve essere un numero intero corrispondente al numero del termine
  • Sono consentiti il ​​trascinamento e le nuove linee principali, anche gli spazi finali dopo le linee
  • La tua richiesta deve essere in grado di gestire almeno fino al decimo termine (9)
  • L'invio deve essere un programma completo o una funzione che accetta input e stampa il risultato
  • Sono consentite rotazioni dell'output, in multipli di 60 gradi, ma la dimensione dei triangoli deve rimanere la stessa, insieme alla rappresentazione
  • È consentito anche andare in senso antiorario
  • Sono vietate le scappatoie standard

Si può presumere che l'input sarà> 0 e che verrà fornito il formato corretto dell'input.

punteggio

Questo è , quindi vince il codice più breve in byte. Buon anno a tutti!


1
il mio linguaggio Turtlèd può prendere input di base 10 ed elaborarlo bene, ma questa sfida sarebbe molto più semplice se prendesse input come unario. sarebbe permesso?
Limone distruttibile

1
@DestructibleWatermelon Sì. L'input deve essere intero, in qualche tipo di forma.
Andrew Li,

freddo. Inizierò a lavorarci adesso
Destructible Lemon

3
aspetta in realtà è ancora molto difficile
Destructible Lemon

Risposte:


13

Befunge, 871 836 798 byte

&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

Provalo online!

Come spesso accade con Befunge, il trucco sta venendo fuori con un algoritmo che ci consente di rendere il modello dall'alto verso il basso, dal momento che non è possibile renderlo in memoria prima con lo spazio limitato disponibile.

Il modo in cui funziona è innanzitutto la creazione di una struttura dati semplice che rappresenti i bordi necessari per disegnare la spirale. Il secondo stadio analizza quindi quella struttura dall'alto verso il basso, rendendo i frammenti di bordo necessari per ogni linea di output.

Usando questa tecnica, possiamo supportare fino a n = 15 nell'implementazione di riferimento prima di iniziare ad avere problemi di overflow nelle celle di memoria a 8 bit. Gli interpreti con una cella di dimensioni maggiori dovrebbero essere in grado di supportare fino a n = 25 prima di esaurire la memoria.


è davvero impressionante ... ma trovi di essere in grado di leggere questi programmi? lol a me sembra così casuale. come costruisce la struttura dei dati? che tipo di struttura dati utilizza? Grazie!
don luminoso

1

vai, 768 byte

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

Questo ovviamente non è ottimale, ma non è un brutto inizio. So che probabilmente è un po 'semplice per gli standard del golf, ma è stato divertente e spero che non mi dispiaccia se lascio alcune note al sé futuro.

Come funziona

Fondamentalmente simulo una 'tartaruga di disegno' come in LOGO su una griglia di pixel ASCII, ma la tartaruga può fare solo questi tre comandi:

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 \

Ora per ogni triangolo, vado in questo modo, dove P è 2x l'ennesimo numero di Padovan:

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

Il quarto 'fd' significa che sto rintracciando il primo lato di ogni triangolo. Questo aiuta a tornare a un buon punto di partenza per il prossimo triangolo. La svolta a metà destra assicura che il triangolo successivo sarà orientato correttamente.


Per golfare la tartaruga, memorizzo 5 variabili di stato nella matrice 态: posizione x, posizione y, velocità x, velocità y e 'runa di disegno'. Ad ogni frame di animazione, x + = x velocity, y + = y velocity e viene disegnata la runa.

Quindi ho impostato la tabella 表 che dice come eseguire effettivamente il turno. Il codice di svolta è complicato a causa del modo in cui funziona l'arte ASCII. Non è un movimento semplice come su un display a pixel. La direzione della tartaruga, determinata dalla velocità xey, determina i cambiamenti necessari per far sembrare la svolta corretta.

Per girare, guarda l'attuale velocità xey, e le combina in un indice.

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

Questo indice viene utilizzato per cercare un set di 5 valori nella tabella 表. Quei 5 valori nella tabella 表 vengono quindi aggiunti a ciascuna delle 5 variabili nello stato 态. La tartaruga viene quindi girata efficacemente e pronta per il prossimo 'fd'.

Per la prima, metà della svolta a destra, c'è una sezione separata della tabella 表. È sfalsato di 7 * 5, o 35, voci dalla prima tabella in 表.

Infine ho fatto una semplice codifica degli interi della tabella in una stringa ASCII.

So che potrei "salvare i byte" rimuovendo l'Hanzi, ma come ho detto, questo non è ottimale e c'è più golf possibile ... Li rimuoverò quando non c'è altra ottimizzazione possibile. Quei Hanzi in realtà hanno un significato vagamente basato sul loro significato reale, e anche se non conosco il cinese, mi aiuta a pensare al programma.

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

Per testare il codice avrai bisogno del file Golang completo, con questa intestazione

package main
import "fmt"

e questo piè di pagina

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

Grazie

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.