Bir Çizgideki Fraktal Noktalar


12

Bazen, gerçekten sıkıldığımda ( gerçekten sıkıldığımda), bir çizgi segmenti çizmeyi ve üzerine noktalar çizmeyi seviyorum.

İlk olarak, belirli bir boyutta, bazı N değeri için 2 ^ N olan bir çizgi parçası çiziyorum. Çizgi, bir dizi .karakterle temsil edilecek .

................

Sonra sol uçta bir nokta çiziyorum. Puanlar Xkarakterlerle gösterilir.

X...............

Sonra bir model takip ediyorum. En son çizilen noktadan başlayarak (A olarak adlandıracağım), satırdaki bir sonraki çizilen noktaya (B) ilerlerim (gerektiği gibi sarar). Sonra, (C) çizgisinde bir sonraki çizilen noktaya ilerlerim. Sonra, bu üçüncü nokta (C) ile bir sonraki halihazırda çizilen nokta (D) arasında yeni bir nokta çiziyorum.

Çizginin etrafına her sarıldığınızda, "orta" sarma biçiminde belirlenir. Yeni çizilen nokta her zaman C'nin sağındadır.

Diyelim ki şu satır benim şimdiki satırım. Sonraki iki noktayı nasıl çizeceğim. Bu örnek için, her önemli noktayı bir harfle etiketleyeceğim.

X...A...X.X...X.
    ^

X...A...B.X...X.
        ^

X...A...B.C...X.
          ^

X...A...B.C...D.
            ^

X...X...X.X.A.X.
            ^

X...X...X.X.A.B.
              ^

C...X...X.X.A.B.
^

C...D...X.X.A.B.
  ^

X.A.X...X.X.X.X.
  ^

Önceki örneğe dönersek, bir sonraki nokta satırın ortasına çizilir.

X.......X.......

Bu belki de biraz özel bir durumdur: bir sonraki noktaya ilerlemek sizi başladığınız yere bırakır. Yararlı olan tek yarım nokta, kendi başına bir nokta çizmenin aksine, "döngüsel" yarım noktadır (hatta yarım nokta).

Aşağıda, çizgiyi buradan sonuna kadar çizeceğim nokta serileri.

X.......X.......
X.......X...X...
X.......X.X.X...
X...X...X.X.X...
X...X...X.XXX...
X.X.X...X.XXX...
X.X.X...XXXXX...

İki bitişik nokta arasına sıkışmış olması gerektiği için artık bir sonraki noktayı çizmek için yer yok, bu yüzden verilen N = 4 değeri için maksimum derinliğe ulaştım. Yukarıdaki listedeki son satır "tamamlandı" ."

Meydan okuma

Amaç, verilen N değeri için tamamlanmış satırı yazdıracak / döndürecek en kısa programı / adlandırılmış işlevi yazmaktır. Yukarıda N = 4 gösterilir.

Giriş

Giriş, negatif olmayan tek bir tamsayı N olacaktır. Oluşturulan çizginin uzunluğu 2 ^ N olacaktır.

Çıktı

Çıktı, 2 ^ N uzunluk .ve Xkarakterlerden oluşan tamamlanmış satır olacaktır . Sondaki yeni satır önemli değil.

Örnek G / Ç

0
X

1
XX

2
X.XX

3
X.X.XXX.

4
X.X.X...XXXXX...

5
X.X.X...X...X...X.XXX.XXX.......

Yanıtlar:


4

Python 2, 137

n=input()
l=[0]*2**n;i=0
while~i%2:i=i/2%2**n;l[i]=1;i=sum([k for k,v in enumerate(l*4)if(k>i)*v][1:3])
print''.join(['.X'[x]for x in l])

Oldukça açık.

Pyth, 49

Aşağı yukarı çeviri. Ana fark, satırı temsil eden bir liste kullanmıyorum, bir dize kullanıyorum.

J*\.^2QW!%Z2K%/Z2lJ=JXJK\X=Zs<tf&q\X@JT>TKU*4J2)J

Çevrimiçi deneyin .

                         Q=input(); Z=0 #implicit
J*\.^2Q                  J = "."*(2^Q)
W!%Z2                    while !(Z%2):
  K%/Z2lJ                  K=(Z/2)%(len(J))
  =JXJK\X                  change J, the point at index K is changed to a "X"
       f          U*4J     filter all elements T in [0, 1, 2, ..., 4*len(J)-1]:
        &q\X@JT>TK           where J[T]=='X' and T>K
     <t               2    only us the second and third element
  =Zs                      and store the sum to Z
)J                       end while and print J

4

Klip , 95

[z?zF#2(z*2*:(#2(z'.'X]'X]]n[Fa[b[q[j[r?=rirFrsrb'X]b]][t[u+*<ut*Blb/+tu2]]g+2jqg+3jq]#qa]%b'X}

3

GolfScript (61 bayt)

~2\?,[]0{.@|$4*.@?2+1$>2<.+~<!4$,*++.2/\1&!}do;`{&!'X.'1/=}+%

Gereken döngü yineleme sayısı A061419 gibi görünüyor , ancak do-döngü bunu hesaplamaktan daha kısadır. Bir divmod, do döngüsünde bir karakter kaydeder. En savurgan olan kısım çıktı dönüşümüdür, ama nasıl geliştireceğimi göremiyorum.



2

Java, 209 207 195 191 bayt

Bu kadar kısa sürede başarabildiğim için şaşırdım. Muhtemelen hala iyileştirme için yer vardır. Her zamanki gibi, öneriler takdir edilecektir :)

Bu a değerini döndürür char[]. Kullanarak arayın a(n).

char[]a;int b,c,d,e=2;char[]a(int f){java.util.Arrays.fill(a=new char[b=1<<f],'.');for(a[0]=88;d+1<e;c=(d+e)/2,a[c%b]=88)e=b(d=b(b(c)));return a;}int b(int f){for(;;)if(a[++f%b]>87)return f;}

Girintili'ye:

char[] a;
int b, c, d, e = 2;

char[] a(int f){
    java.util.Arrays.fill(
            a = new char[
                    b = 1 << f
                    ]
            , '.'
    );
    for(
            a[0] = 88;
            d + 1 < e;
                c = (d + e) / 2,
                a[c % b] = 88
        )
        e = b(
                d = b(
                        b(c)
                )
        );
    return a;
}

int b(int f){
    for (;;)
        if (a[++f % b] > 87)
            return f;
}

Peter sayesinde 12 bayt :)
TNT sayesinde 4 bayt;)


(c%b+b)%b? cOlumsuz olmayı mı bekliyorsunuz ?
Peter Taylor

c=0ve d=0sadece cve olarak kısaltılabilir d. intsınıf düzeyinde tanımlanan tipler otomatik olarak 0 olarak başlatılır.
TNT

1

Haskell, 182 bayt

(a:b)%(c:d)|a<c=a:b%(c:d)|1<2=c:(a:b)%d
f i=putStr$map(!(0:g[0,n..]))[0..n-1]where n=2^i;e!l|e`elem`l='X'|1<2='.';g(_:_:c:d:r)|m==c=[]|1<2=mod m n:g((d:r)%[m,m+n..])where m=div(c+d)2

Kullanımı: f 5. Çıktı: X.X.X...X...X...X.XXX.XXX........

Ne yazık ki Haskell'in standart kütüphanelerde birleştirme işlevi yok, bu yüzden kendime (-> %) sahip olmam gerekiyor . Neyse ki sadece sonsuz listeleri birleştirmek zorundayım, bu yüzden temel vakaları, yani boş listeleri kapsamak zorunda değilim. Hala 40 bayta mal oluyor.

Nasıl çalışır: Xs bir dizide doğrudan ayarlamak yerine, bulundukları konumların bir listesini tutmak. Dahası etrafta sarılmıyorum 2^Nama sonsuza kadar pozisyonları artırmaya devam ediyorum (örneğin Xön tarafta bir N ile 2 = için , konum listesi gibi görünüyor [0,4,8,12,16,20,…]). 3. ve 4. elemanı alıyorum ( cve d), yeni pozisyonu hesaplıyorum, (c+d)/2çıktı listesi için saklıyorum, eski pozisyon listesini (4 d) pozisyonundan başlayarak yenisiyle başlayıp (c+d)/2tekrar ediyorum. (c+d)/2Eşit olduğunda dururum c. Sonunda 0çıkış listesine bir ekler Xve verilen konumlarda ve .başka yerlerde s yazdırır .

step by step example, N=2

step  position list       (c+d)/2  output     lists to merge (pos. list for next round)
                                   list       old list from d on / new list from (c+d)/2

  #1  [0,4,8,12,16,…]       10     [10]          [12,16,20,24,…] / [10,14,18,22,…]
  #2  [10,12,14,16,18,…]    15     [10,15]       [16,18,20,22,…] / [15,19,23,27,…]
  #3  [15,16,18,19,20,…]    18

stop here, because c equals (c+d)/2

add 0 to the output list: [0,10,15]
take all elements modulo 2^N: [0,2,3]
print X at position 0, 2 and 3 

1

Mathematica 110 102 112 108

a=Array["."&,n=2^Input[]];a[[Mod[Round@{n/2,n}//.{x_,y_,z___}/;y-x>1:>{z,x+n,(x+y)/2+n,y+n},n]+1]]="X";""<>a
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.