Hilbert Eğrisini Çiz


12

Bir Hilbert Eğrisi bir tür boşluk doldurma eğrisidir ve temel olarak bir çizgiyi bir düzleme eşler. Çizgideki her nokta düzlemdeki sadece bir noktaya karşılık gelir ve düzlemdeki her nokta çizgideki sadece bir noktaya karşılık gelir. Hilbert Eğrisinin 0 ila 4 iterasyonları gösterilmiştir:

0'dan 4'e kadar yineleme:

Bu görevin amacı: Yukarıda tanımlandığı gibi Hilbert Eğrisi'nin dördüncü yinelemesini çizen kod yazma. Kodunuz tam olmalıdır - başka bir deyişle, Hilbert Eğrisi'ni çizmek için bir işlev oluşturursanız, kodunuzun bu işlevi çağırması gerekir. Çıktı doğrudan ekranda görüntülenebilir veya çıktıyı bir görüntü dosyasına yazabilirsiniz. Eğri döndürülebilir veya ters çevrilebilir, ancak çizgiler dik açılarda kesişmelidir ve çıktı uzatılamaz. ASCII sanatı takdir edilir, ancak kabul edilmeyecektir. Bayt cinsinden en kısa kod kazanır!


Girdi sayısı kaçtır? Veya en az 4 değer seçebilir miyiz?
Luis Mendo

ASCII sanatı grafik olarak kabul edilir mi?
Gabriel Benamy

Hayır; üzgünüm - o zaman başka bir sorunun kopyası olurdu
J. Antonio Perez

@JorgePerez Eğrinin farklı bir yönü olabilir mi? Örneklerinizin dikey olarak döndürülmüş veya 90 derecelik bir döndürme sürümü gibi
Luis Mendo

Evet! Genel şekil hala kare olmasına rağmen
J. Antonio Perez

Yanıtlar:


7

R, 90 bayt

n=scan();a=1+1i;b=1-1i;z=0;for(k in 1:n)z=c((w<-1i*Conj(z))-a,z-b,z+a,b-w)/2;plot(z,t="s")

@Luis Mendo tarafından gönderilen bağlantıda kullanılan algoritmanın utanmaz R-portu.

İçin n=5biz almak:

resim açıklamasını buraya girin


7

MATL , 39 38 bayt

O5:"tZjJ*JQ-wJq+t2+&y2j+_v2/]XG25Y01ZG

Bu yineleme sayısını girdi olarak alır. Sabit kodlamak istiyorsanız, inumarayla değiştirin .

Program, burada gösterilen Jonas Lundgren'in Matlab kodunun bir limanıdır .

Sonuç aşağıda gösterilmiştir. MATL Online'da da deneyebilirsiniz ! Çıktıyı üretmek birkaç saniye alır. Bu derleyici deneyseldir; başlangıçta çalışmazsa sayfayı yenilemeniz ve tekrar "Çalıştır" a basmanız gerekebilir.

resim açıklamasını buraya girin

açıklama

O          % Push 0. This is the initial value of "z" in the original code
5:"        % Do 5 times
  t        %   Duplicate
  Zj       %   Complex conjugate
  J*       %   Multiply by 1j (imaginary unit). This is "w" in the original code
  JQ-      %   Subtract 1+1j
  w        %   Swap: brings copy of "z" to top
  Jq+      %   Add 1-1j
  t        %   Duplicate
  2+       %   Add 2
  &y       %   Duplicate the third element from top
  2j+_     %   Add 2j and negate
  v        %   Concatenate the three matrices vertically
  2/       %   Divide by 2
]          % End
XG         % Plot (in complex plane). The numbers are joined by straight lines
25Y0       % Push string 'square'
1ZG        % Make axis square

Kodunuzun nasıl çalıştığını açıklayabilir misiniz?
J. Antonio Perez

Algoritma bağlantıdaki gibidir. Ama bir açıklama ekleyeceğim
Luis Mendo

@Jorge Açıklama eklendi
Luis Mendo


@flawr Jonas Lundgren'e verilen tüm kredi :-)
Luis Mendo

6

MATLAB, 264 262 161 bayt

Temelde hilbert eğrisinin "türevini" hesaplamamız dışında, hala `` cumsum`` aracılığıyla "bütünleştirdiğimiz" dışında, bu hala aynı şekilde çalışır. Bu, kod boyutunu bir sürü bayt azaltır.

function c;plot(cumsum([0,h(1,1+i,4)]));axis equal;end function v=h(f,d,l);v=d*[i*f,1,-i*f];if l;l=l-1;D=i*d*f;w=h(f,d,l);x=h(-f,D,l);v=[x,D,w,d,w,-D,-x];end;end

Eski versiyon

Bu sadece basit bir özyinelemeli yaklaşımdır. Basitlik için vektörel bilgileri saklamak için karmaşık sayılar kullandım. Parçadaki eğriyi değiştirebilirsiniz h(0,1,1+i,4). İlk argüman p=0başlangıç ​​konumudur, ikinci argüman fyönelim ( +1veya -1) için bir bayraktır , üçüncü argüman değrinin çizilmesi gereken yön / rotasyon ve dördüncüsü lözyineleme derinliğidir.

function c;hold on;h(0,1,1+i,4);axis equal;end function p=h(p,f,d,l);q=@plot;if l;l=l-1;d=i*d*f;p=h(p,-f,d,l);q(p+[0,d]);p=p+d;d=-i*d*f;p=h(p,f,d,l);q(p+[0,d]);p=p+d;p=h(p,f,d,l);d=-i*d*f;q(p+[0,d]);p=p+d;p=h(p,-f,d,l);else;q(p + d*[0,i*f,1+i*f,1]);p=p+d;end;end

Eski sürümlerde böyle görünüyor:

2015b'de böyle görünüyor:

->

1
Matlab R2015b'de renkler <3 olarak çizilir
Luis Mendo

Haha so cool :)
Kusur

@LuisMendo Şimdi cumsumsadece harika bir fikir ile biraz golf başardı !
flawr

3

MATLAB / Oktav, 202 bayt

Ben fark @LuisMendo ilintili sürümü is önceki çok daha kısaydı "el yapımı" çözüm ancak tamamen farklı bir yaklaşım kullanır. Şimdi golf versiyonunu CW olarak gönderiyorum:

Bu sürüm Lindenmayer sistem yaklaşımına dayanmaktadır:

A=zeros(0,2);B=A;C=A;D=A;n=[0,1];e=[1,0];for k=1:4;a=[B;n;A;e;A;-n;C];b=[A;e;B;n;B;-e;D];c=[D;-e;C;-n;C;e;A];D=[C;-n;D;-e;D;n;B];A=a;B=b;C=c;end;A=[0,0;cumsum(A)];plot(A(:,1),A(:,2));axis off;axis equal

resim açıklamasını buraya girin


3

JavaScript (ES6), 266 ... 233 232 bayt

Hilbert Curve'un SVG sunumu.

document.write('<svg><path fill=none stroke=red d="M8 8'+(f=(i,s='2',d=x=y=8)=>i?f(i-1,s.replace(/./g,c=>[32410401423,,10432423401][+c]||c)):s.replace(/./g,c=>c-4?(d+=c&1&&c-2,''):`L${x+=4-'4840'[d&=3]} ${y+=4-'0484'[d]}`))(5)+'">')

Neil sayesinde 1 bayt kaydedildi


1
Denefill=none
Neil

2

Python 3, 177 175 171 bayt

Hilbert eğrisi için Lindenmayer sisteminin basit bir uygulaması. Golf önerileri hoş geldiniz!

Düzenleme: Kade sayesinde -2 bayt. Hilbert eğrisinin nasıl oluşturulduğunu yeniden yapılandırmaktan -3 bayt. ETHproductions sayesinde -1 bayt.

from turtle import*;s="a";exec('t=""\nfor c in s:t+=c>"F"and"+-abFF-+baFFba-+FFab+-"[c<"b"::2]or c\ns=t;'*5)
for c in s:
 if"-">c:rt(90)
 elif"F">c:lt(90)
 elif"a">c:fd(9)

resim açıklamasını buraya girin

Ungolfing

import turtle

hilbert_seq = "a"

for _ in range(5):
    new_seq = ""
    for char in hilbert_seq:
        if char == "a":
            new_seq += "-bF+aFa+Fb-"
        elif char == "b":
            new_seq += "+aF-bFb-Fa+"
        else:
            new_seq += char
    hilbert_seq = new_seq

for char in hilbert_seq:
    if char == "F":
        turtle.forward(9)
    elif char == "+":
        turtle.right(90)
    elif char == "-":
        turtle.left(90)

Eğer formu nasıl değiştirilmesi tiki bayt kaydedebilirsiniz: t+=[[c,"+AF-BFB-FA+"][c=="B"],"-BF+AFA+FB-"][c=="A"]. Desen ikisi için neredeyse aynı olduğundan, bunu kullanmanın bir yolu olup olmadığını merak ediyorum ..
Kade

Belki değiştirmek if c>"E":için if"E"<c:bir byte kaydetmek için?
ETHproductions

1

MSWLogo (Sürüm 6.5b), 136 bayt

Buradaki son Hilbert eğrisi programına dayanmaktadır .

to h :n :a :l
if :n=0[stop]
rt :a
h :n-1(-:a):l
fd :l
lt :a
h :n-1 :a :l
fd :l
h :n-1 :a :l
lt :a
fd :l
h :n-1(-:a):l
rt :a
end
h 5 90 9

hYineleme sayısı :n(1 tabanlı), açı :a, uzunluk alan bir işlev tanımlanır :l. Özyinelemeyi :asağlamak için iki durumda negatif açı ile daha düşük bir yinelemeyi çağırmak özyinelemelidir .

  • rt :a, lt :akaplumbağayı (yolu izlenen üçgen şey) sağa, sola doğru :adöndürün.
  • fd :lkaplumbağayı :ladım adım ileri taşır .

Son olarak, işlev denir: h 5 90 9. Kaplumbağa fazladan 2 bayt saklanabilir ht.

(5-1) - yineleme


Sol üst köşede neler oluyor?
Kusur

@flawr Bu kaplumbağa. Ekleyerek gizlenebilir ht.
Monica için

1

Mathematica 128 Bayt

Graphics[Line@AnglePath[Total/@Split[Cases[Nest[#/.{-2->(s=##&@@#&)[l={-1,2,0,1,-2,0,-2,1,0,2,-1}],2->s@-l}&,{-2},4],-1|1|0],#!=0&][[;;-2,;;-2]]*Pi/2]]

İsterseniz yukarıdaki 4'ü farklı sayıda yineleme ile değiştirin.

Dize dizileri yerine tamsayı dizileri olan bir Lindenmayer sistemi olarak yapılır, böylece ikinci üretim kuralı sadece ilk kuralın negatifidir. Bu sürüm 151 bayttır.

Jonas Lundgren'in MATLAB kodunun limanı sadece 128 bayt.

z=0;Graphics[Line[{Re[#],Im[#]}&/@Flatten[Table[w=I*Conjugate[z];z={w-(a=1+I),z-(b=1-I),z+a,b-w}/2,{k,5}][[5]]]],AspectRatio->1]

Mathematica'nın gelecekteki bir versiyonunda, bunun gerçekten kısa olabileceğini görüyorum:

Graphics@HilbertCurve[n]

http://mathworld.wolfram.com/HilbertCurve.html


1

LindenMASM , 63 Bayt

LindenMASM cevabı olan başka bir soru mu var? Müthiş!

STT
AXI A
INC 5
SET F 0
RPL A -BF+AFA+FB-
RPL B +AF-BFB-FA+
END

Bir kez daha, Python'un bazı çizim hataları nedeniyle turtle, bazen bunu çalıştırdığınızda tüm çizim orada değildir. Ancak bunun gerçekten işe yaradığını görebilirsiniz:

4. yineleme

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.