Bir ASCII Padovan Spiral Üret


22

Bu, bu mücadelenin ASCII versiyonudur . İlk gönderi Martin Ender tarafından istek başına ayrıldı

Giriş

Fibonacci Dizisine benzer şekilde, Padovan Dizisi ( OEIS A000931 ), dizide önceki terimler eklenerek üretilen bir sayı dizisidir. İlk değerler şöyle tanımlanır:

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

0, 1 ve 2. terimlerin tümü 1'dir. Yinelenme ilişkisi aşağıda belirtilmiştir:

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

Böylece, aşağıdaki sırayı verir:

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

Bu sayıları eşkenar üçgenlerin yan uzunlukları olarak kullanmak, hepsini bir araya getirdiğinizde Fibonacci Spiral gibi, güzel bir spiral oluşturur:

görüntü tanımını buraya girin

Görüntü Wikipedia'nın izniyle


Görev

Göreviniz bu spirali ASCII sanatı ile yeniden oluşturan ve hangi terime karşılık gelen bir program yazmak. Yan uzunlukta 1 bir üçgenin (1 karakter) bir ASCII'de güzel bir şekilde temsil edilmesi imkansız olduğundan, yan uzunluklar 2 katıyla genişletilir. Böylece, yan uzunluk 1'in üçgeni aslında şöyle gösterilir:

 /\
/__\

Bu nedenle, örneğin, giriş 5 ise (5. terim), çıktı şöyle olmalıdır:

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

İlk 5 terim 1, 1, 1, 2, 2 idi, bu yüzden üçgen dilatasyon nedeniyle yan uzunlukları 2, 2, 2, 4, 4 idi. Giriş 8 için başka bir örnek:

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

kurallar

  • Sonucu yazdırmanız ve girişin terim numarasına karşılık gelen bir tam sayı olması gerekir
  • İzleyen ve önde gelen yeni satırlara izin verilir, satır sonundan sonraki alanlara da izin verilir
  • Gönderiminiz en az 10. döneme kadar devam edebilmelidir (9).
  • Gönderiminiz girdi alan ve sonucu basan tam bir program veya işlev olmalıdır
  • Çıktının dönüşlerine, 60 derecelik katlarda izin verilir, ancak üçgenlerin boyutu, gösterimle birlikte aynı kalmalıdır
  • Saat yönünün tersine gitmek de mümkündür
  • Standart boşluklar yasaktır

Girişin> 0 olacağını ve doğru giriş formatı verileceğini varsayabilirsiniz.

puanlama

Bu , yani bayt cinsinden en kısa kod kazanır. Herkese mutlu yıllar!


1
Dilim Turtlèd, 10'luk girdiyi alabilir ve iyi işleyebilir, ancak bu zorluk, girdiyi unary olarak alırsa çok daha kolay olacaktır. buna izin verilir mi?
Yıkılabilir Limon

1
@ Yıkılabilir Karpuz Evet. Girdi sadece bir çeşit biçimde tamsayı olmalıdır.
Andrew Li

güzel. Şimdi üzerinde çalışmaya başlayacağım
Yıkılabilir Limon

3
bekle aslında hala çok zor
Yıkılabilir Limon

Yanıtlar:


13

Befunge, 871 836 798 bayt

&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

Çevrimiçi deneyin!

Befunge'de olduğu gibi, hile, kalıbı yukarıdan aşağıya yapmamıza izin veren bir algoritma ile geliyor, çünkü sadece sınırlı alanla ilk önce onu belleğe dönüştürmek mümkün değil.

Bunun işleyişi, ilk olarak, spirali çekmek için gereken kenarları temsil eden basit bir veri yapısı oluşturmaktır. İkinci aşama daha sonra bu yapıyı yukarıdan aşağıya ayrıştırır ve her çıktı satırı için gereken kenar parçalarını oluşturur.

Bu tekniği kullanarak, 8 bitlik bellek hücrelerinde taşma sorununu yaşamaya başlamadan önce referans uygulamasında n = 15'e kadar destekleyebiliriz. Daha büyük hücre büyüklüğüne sahip tercümanlar, bellek bitmeden önce n = 25 değerine kadar destek verebilmelidir.


bu çok etkileyici ... ama bu programları okuyabildiğini mi düşünüyorsun? bana lol çok rastgele görünüyor. veri yapısını nasıl inşa eder? ne tür bir veri yapısı kullanıyor? Teşekkürler!
don

1

git, 768 bayt

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

Bu elbette optimal değil, ama kötü bir başlangıç ​​değil. Golf standartları için muhtemelen biraz basit olduğunu biliyorum, ama eğlenceliydi ve gelecekteki benime bazı notlar bırakmamın sakıncası olmadığını umuyorum.

Nasıl çalışır

Temelde bir ASCII piksel ızgarası üzerindeki LOGO'daki gibi bir 'çizim kaplumbağası' simülasyonu yapıyorum, ancak kaplumbağa bu üç komutu sadece yapabilir:

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 \

Şimdi her üçgen için, P bölü Padovan sayısının 2 katı olduğu için böyle giderim:

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

Dördüncü “fd”, her üçgenin ilk tarafını yeniden izleyeceğim anlamına geliyor. Bu, bir sonraki üçgen için güzel bir başlangıç ​​noktasına dönmenize yardımcı olur. Yarım sağa dönüş, bir sonraki üçgenin doğru yönde olmasını sağlar.


Kaplumbağayı golf oynamak için 5 durum değişkenini 态: x pozisyonu, y konumu, x hızı, y hızı ve 'çizim rune' dizisinde saklarım. Her animasyon karesinde, x + = x hız, y + = y hız ve rune çizilir.

Ardından dönüşü nasıl gerçekleştireceğimizi söyleyen tablo 表 kurdum. Anahtar teslimi, ASCII sanatının çalışma şekli nedeniyle aldatıcı. Bir piksel ekranındaki gibi basit bir hareket değil. Kaplumbağanın yönü, x ve y hızıyla belirlenir ve sıranın düzgün görünmesi için gereken değişiklikleri belirler.

Dönmek için, mevcut x ve y hızına bakar ve bunları bir endekste birleştirir.

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

Bu indeks 表 tablosunda 5 değerden oluşan bir grubu aramak için kullanılır. Tablodaki 5 bu 5 değer daha sonra 态 durumundaki 5 değişkenin her birine eklenir. Kaplumbağa daha sonra etkin bir şekilde döndürülür ve bir sonraki 'fd' için hazırdır.

Dördüncü, sağ dönüşün yarısı için, 表 tablonun ayrı bir bölümü var. İlk tablodaki 表 içindeki girişler 7 * 5 veya 35 ile dengelenir.

Son olarak, tablonun tamsayılarını bir ascii dizgisine basit bir şekilde kodladım.

Hanzi'yi kaldırarak 'bayt' kaydedebildiğimi biliyorum ama dediğim gibi, bu optimal değil ve daha fazla golf mümkün ... Başka bir olası optimizasyon olmadığında bunları kaldıracağım. Bu Hanzi'lerin aslında gerçek anlamlarına dayanarak gevşek bir anlamı var ve Çince bilmeme rağmen, program hakkında düşünmeme yardımcı oluyor.

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

Kodu test etmek için bu başlık ile tam golang dosyasına ihtiyacınız olacak.

package main
import "fmt"

ve bu altbilgi

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

Teşekkürler

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.