Gambarkan Kurva Hilbert

12

Hilbert Curve adalah jenis kurva pengisian ruang, dan pada dasarnya memetakan garis ke pesawat. Setiap titik dalam garis hanya bersesuaian dengan satu titik di bidang, dan setiap titik di bidang tersebut bersesuaian dengan hanya satu titik pada garis. Yang ditampilkan adalah iterasi 0 hingga 4 dari Kurva Hilbert:

Iterasi 0 hingga 4:

Tujuan dari tugas ini: Tulis kode yang menggambarkan iterasi keempat Kurva Hilbert, sebagaimana didefinisikan di atas. Kode Anda harus lengkap - dengan kata lain, jika Anda membuat fungsi untuk menggambar Kurva Hilbert, kode Anda harus memanggil fungsi itu. Outputnya dapat ditampilkan langsung di layar, atau Anda dapat menulis output ke file gambar. Kurva dapat diputar atau dibalik, tetapi garis harus berpotongan pada sudut kanan dan output tidak dapat ditarik. Seni ASCII dihargai tetapi tidak akan diterima. Kode terpendek dalam byte menang!

J. Antonio Perez
sumber
Apakah berapa kali input? Atau bisakah kita memilih nilai setidaknya 4?
Luis Mendo
Apakah seni ASCII dianggap grafis?
Gabriel Benamy
Tidak; maaf - maka itu akan menjadi duplikat dari pertanyaan lain
J. Antonio Perez
@JorgePerez Bisakah kurva memiliki orientasi yang berbeda? Seperti versi putar-balik atau putar 90 derajat dari contoh Anda
Luis Mendo
Iya! Meskipun bentuk keseluruhan masih harus persegi
J. Antonio Perez

Jawaban:

7

R, 90 byte

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")

Shameless R-port dari algoritma yang digunakan dalam tautan yang diposting oleh @Luis Mendo.

Untuk n=5kita dapatkan:

masukkan deskripsi gambar di sini

Billywob
sumber
7

MATL , 39 38 byte

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

Ini mengambil jumlah iterasi sebagai input. Jika Anda ingin hard-code-nya, ganti idengan nomornya.

Program ini adalah port dari kode Matlab oleh Jonas Lundgren yang ditampilkan di sini .

Hasilnya ditunjukkan di bawah ini. Anda juga dapat mencobanya di MATL Online! Butuh beberapa detik untuk menghasilkan output. Kompiler ini bersifat eksperimental; Anda mungkin perlu me-refresh halaman dan tekan "Run" lagi jika awalnya tidak bekerja.

masukkan deskripsi gambar di sini

Penjelasan

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
Luis Mendo
sumber
Bisakah Anda menjelaskan cara kerja kode Anda?
J. Antonio Perez
Algoritma persis seperti pada tautan. Tetapi saya akan menambahkan penjelasan
Luis Mendo
@Jorge Explanation ditambahkan
Luis Mendo
omg, yang Anda
miliki menjadi
@ flawr Semua kredit untuk Jonas Lundgren :-)
Luis Mendo
6

MATLAB, 264 262 161 byte

Ini masih sangat mirip, kecuali bahwa kita pada dasarnya menghitung "turunan" dari kurva hilbert, yang kemudian kita "integrasikan" melalui `cumsum``. Ini mengurangi ukuran kode dengan cukup banyak byte.

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

Versi lama

Ini hanyalah pendekatan rekursif. Saya menggunakan bilangan kompleks untuk menyimpan informasi vektor untuk kesederhanaan. Anda dapat mengubah kurva di bagian tersebut h(0,1,1+i,4). Argumen pertama p=0adalah posisi awal, argumen kedua fadalah bendera untuk orientasi ( +1atau -1), argumen ketiga dadalah arah / rotasi di mana kurva harus digambar dan yang keempat ladalah kedalaman rekursi.

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

Ini seperti apa di versi yang lebih lama:

Seperti di 2015b:

->
cacat
sumber
1
Dalam Matlab R2015b, plot itu berwarna <3
Luis Mendo
Haha keren sekali :)
flawr
@LuisMendo Saya sekarang bisa bermain golf sedikit dengan cumsumide yang hanya brilian!
flawr
3

MATLAB / Oktaf, 202 byte

Saya melihat versi @LuisMendo terkait yaitu adalah cara lebih pendek dari sebelumnya solusi "buatan tangan" tetapi menggunakan pendekatan yang sama sekali berbeda. Saya memposting versi golf di sini sekarang sebagai CW:

Versi ini didasarkan pada pendekatan sistem Lindenmayer:

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

masukkan deskripsi gambar di sini

cacat
sumber
3

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

Render SVG dari Kurva Hilbert.

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)+'">')

Disimpan 1 byte berkat Neil

Arnauld
sumber
1
Cobafill=none
Neil
2

Python 3, 177 175 171 byte

Implementasi sederhana dari sistem Lindenmayer untuk kurva Hilbert. Selamat datang saran bermain golf!

Edit: -2 byte terima kasih kepada Kade. -3 byte dari restrukturisasi bagaimana kurva Hilbert dibangun. -1 byte dengan terima kasih kepada ETHproductions.

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)

masukkan deskripsi gambar di sini

Tidak melakukanolf

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)
Sherlock9
sumber
Mengubah cara Anda membentuk tdapat menyimpan dua byte: t+=[[c,"+AF-BFB-FA+"][c=="B"],"-BF+AFA+FB-"][c=="A"]. Karena polanya hampir sama untuk mereka berdua, saya ingin tahu apakah ada cara untuk menggunakannya ..
Kade
Mungkin berubah if c>"E":menjadi if"E"<c:untuk menyimpan byte?
ETHproduk
1

MSWLogo (Versi 6.5b), 136 byte

Berdasarkan program kurva Hilbert akhir di sini .

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

Suatu fungsi hdidefinisikan, yang mengambil jumlah iterasi :n(berbasis 1), sudut :a, panjang :l. Itu rekursif, memanggil iterasi yang lebih rendah dari dirinya sendiri dengan sudut :adinegasikan dalam dua contoh untuk mendapatkan orientasi yang benar.

  • rt :a, lt :aputar kura-kura (benda segitiga yang jalurnya dilacak) ke kanan, sedikit demi sedikit :a.
  • fd :lmenggerakkan penyu dengan :llangkah-langkah.

Akhirnya, fungsi ini dipanggil: h 5 90 9. Penyu bisa disembunyikan selama 2 byte ekstra ht,.

(5-1) - iterasi ke-4

untuk Monica
sumber
Apa yang terjadi di sudut kiri atas?
flawr
@ flawr Itu kura-kura. Itu bisa disembunyikan dengan menambahkan ht.
untuk Monica
1

Mathematica 128 Bytes

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

Ganti 4 di atas dengan jumlah iterasi yang berbeda jika Anda mau.

Dilakukan sebagai sistem Lindenmayer dengan urutan bilangan bulat dan bukan urutan string sehingga aturan produksi kedua hanyalah negatif dari aturan pertama. Versi ini adalah 151 byte.

Port kode MATLAB Jonas Lundgren hanya 128 byte.

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]

Saya melihat bahwa dalam versi Mathematica yang akan datang, ini mungkin menjadi sangat singkat, seperti:

Graphics@HilbertCurve[n]

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

Kelly Lowder
sumber
1

LindenMASM , 63 Bytes

Pertanyaan lain dengan jawaban LindenMASM? Luar biasa!

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

Sekali lagi, karena beberapa bug menggambar dengan Python turtle, kadang-kadang ketika Anda menjalankan ini seluruh gambar tidak ada. Namun Anda dapat melihatnya benar-benar berfungsi:

Iterasi 4

Kade
sumber