Gambarlah kurva Hilbert menggunakan garis miring


30

The kurva Hilbert adalah mengisi fraktal ruang yang dapat diwakili sebagai sistem Lindenmayer dengan generasi-generasi yang terlihat seperti ini:
Kurva Hilbert
Berkat http://www.texample.net/tikz/examples/hilbert-curve/ untuk gambar.

Tujuan

Tuliskan program sesingkat mungkin (dalam byte) yang mengambil bilangan bulat positif dari stdin dan menggambar kurva Hilbert urutan ke-5 dengan menggunakan hanya garis miring, garis miring, spasi, dan baris baru.

Misalnya, jika inputnya adalah 1output harus

 \
\/

Jika inputnya adalah 2output harus

  /
  \/\
/\   \
 / /\/
 \ \
  \/

Jika inputnya adalah 3output harus

       \
     /\/
    /   /\
    \/\ \ \
  /\  / / /
 / /  \/  \/\
 \ \/\  /\   \
\/   / / / /\/
  /\/ /  \ \
  \   \/\ \/
   \/\   \
     / /\/
     \ \
      \/

Dan seterusnya. (Mereka terlihat lebih bagus jika Anda menempelkannya ke sesuatu dengan jarak garis yang lebih sedikit.)

Output tidak boleh mengandung baris baru di atas atau di bawah ekstremitas kurva, atau spasi tambahan pada garis apa pun.

Jawaban:


10

Ruby, 247 230 205 karakter

r=?D
y=d=0
z=(1..2*x=2**gets.to_i.times{r.gsub!(/\w/){$&<?H?'-H~+D~D+~H-':'+D~-H~H-~D+'}}-1).map{' '*2*x}
r.bytes{|c|c>99?(z[y-=s=-~d/2%2][x-=1-d/2]='/\\'[d%2]
x+=d/2
y+=1-s):d-=c
d%=4}
puts z.map &:rstrip

Pendekatan penyu ASCII menggunakan representasi Lindenmayer (coba di sini ).

Terima kasih banyak kepada @Ventero untuk bermain golf lagi.


Golf ini sedikit lebih, harap Anda tidak keberatan: ideone.com/kvcPWT - .map(&:rstrip)harus ditambahkan untuk memenuhi persyaratan "tidak ada spasi tambahan".
Ventero

@Ventero Terima kasih. Harap Anda tidak keberatan bahwa saya mengambil solusi Anda - Anda bahkan dapat membuang paranthes di sekitar argumen peta.
Howard

Ah, tentu saja! Saya juga baru menyadari bahwa dimungkinkan untuk menyejajarkan definisi xdan mempersingkat penugasan ke ydan d, dengan total 205 karakter (lihat tautan yang sama seperti sebelumnya).
Ventero

12

Python, 282

from numpy import*
def r(n):
 x=2**n-2;b=3*x/2+1;c=x/2+1;a=zeros((x*2+2,)*2,int);a[x+1,x+1]=1;a[b,x/2]=a[x/2,b]=-1
 if n>1:s=r(n-1);a[:x,c:b]=rot90(s,3)*-1;a[c:b,:x]|=rot90(s)*-1;a[c:b,x+2:]|=s;a[x+2:,c:b]|=s
 return a
for l in r(input()):print''.join(' /\\'[c] for c in l).rstrip()

Ini menggunakan pendekatan rekursif untuk membangun kurva urutan Hilbert ke-n dari kurva sebelumnya. Kurva direpresentasikan sebagai susunan numpy 2d untuk pengirisan dan manipulasi yang lebih baik.

Berikut ini beberapa contohnya:

$ python hilbert.py
2
  /
  \/\
/\   \
 / /\/
 \ \
  \/
$ python hilbert.py
3
       \
     /\/
    /   /\
    \/\ \ \
  /\  / / /
 / /  \/  \/\
 \ \/\  /\   \
\/   / / / /\/
  /\/ /  \ \
  \   \/\ \/
   \/\   \
     / /\/
     \ \
      \/
$ python hilbert.py
4
              /
              \/\
            /\   \
           / / /\/
           \ \ \  /\
         /\/  \/  \ \
        /   /\  /\/ /
        \/\ \ \ \   \/\
      /\  / /  \ \/\   \
     / /  \/ /\/   / /\/
     \ \/\  /   /\/ /   /\
   /\/   /  \/\ \   \/\ \ \
  /   /\/ /\  / / /\  / / /
  \/\ \  / /  \/ / /  \/  \/\
/\   \ \ \ \/\   \ \/\  /\   \
 / /\/  \/   / /\/   / / / /\/
 \ \  /\  /\/  \  /\/ /  \ \
  \/  \ \ \  /\/  \   \/\ \/
    /\/ / / /   /\ \/\   \
    \   \/  \/\ \ \  / /\/
     \/\  /\  / / /  \ \
       / / /  \/  \/\ \/
       \ \ \/\  /\   \
        \/   / / / /\/
          /\/ /  \ \
          \   \/\ \/
           \/\   \
             / /\/
             \ \
              \/

5

Malsys - 234 221 karakter

Saya mencium beberapa sistem L di sini :) Malsys adalah penerjemah L-sistem online. Ini bukan entri yang benar-benar serius tetapi saya merasa solusi ini agak menarik.

Sintaks dari Malsys tidak benar-benar baik untuk bermain golf karena mengandung banyak kata kunci yang panjang tapi tetap saja, ini cukup pendek, mudah dibaca, dan ekspresif.

lsystem HilbertCurveAscii {
    set symbols axiom = R;
    set iterations = 5;
    set rightAngleSlashMode = true;
    interpret F as DrawLine;
    interpret + as TurnLeft;
    interpret - as TurnRight;
    rewrite L to + R F - L F L - F R +;
    rewrite R to - L F + R F R + F L -;
}
process all with HexAsciiRenderer;

http://malsys.cz/g/3DcVFMWn

Penerjemah: http://malsys.cz/Process

Versi golf:

lsystem H{set symbols axiom=R;set iterations=3;set
rightAngleSlashMode=1;interpret.as DrawLine;interpret+as
TurnLeft;interpret-as TurnRight;rewrite L to+R.-L.L-.R+;rewrite
R to-L.+R.R+.L-;}process H with HexAsciiRenderer;

Dan bagaimana dengan kurva Gosper heksagonal Ascii? :)

      ____
 ____ \__ \
 \__ \__/ / __
 __/ ____ \ \ \
/ __ \__ \ \/
\ \ \__/ / __
 \/ ____ \/ /
    \__ \__/
    __/

http://malsys.cz/g/ae5v5vGB


2

JavaScript (ES6) 313 340

Sunting Beberapa karakter yang dihapus menggunakan praktik yang benar-benar buruk - seperti variabel global, bukan nilai balik dari fungsi H

Mengkonversi x, posisi y ke jarak d (lihat Wikipedia ) untuk setiap x, y dan memverifikasi jika posisi terdekat terhubung,

Tes di konsol FireFox. Input melalui popup, output melalui console.log.

Tidak ada spasi tambahan dan tidak ada baris baru di atas atau di bawah gambar. Tapi setiap baris diakhiri dengan baris baru, saya pikir itu cara yang tepat untuk membuat gambar seni Ascii.

n=1<<prompt(),d=n-1
H=(s,x,y)=>{for(w=0;s>>=1;)p=x&s,q=y&s,w+=s*s*(3*!!p^!!q),q||(p&&(x=s-1-x,y=s-1-y),[x,y]=[y,x])}
for(r=t='';++r<d+n;t+='\n')for(r>d?(x=r-d,f=x-1):(f=d-r,x=0),t+=' '.repeat(f),z=r-x;x<=z;)
h=H(n,y=r-x,x)|w,H(n,y,x-1),x?t+=' \\'[h-w<2&w-h<2]:0,H(n,y-1,x++),y?t+=' /'[h-w<2&w-h<2]:0
console.log(t)

Anda dapat menyimpan beberapa karakter dengan menggunakan alertalih-alih console.log. Anda juga memiliki ruang ekstra setelah forpada baris keempat, dan Anda harus dapat menyingkirkan jeda baris terakhir.
Bob

@ Bob ya sebenarnya saya bisa menyimpan sekitar 15 karakter lagi, saya menyerah melihat saya lebih dari 300. Saya tidak suka menggunakan 'lansiran' karena gambar benar-benar tidak dapat dikenali tanpa font nada tetap
edc65

2

Perl, 270 Karakter

Super golf

$_=A,%d=<A -BF+AFA+FB- B +AF-BFB-FA+>,$x=2**($n=<>)-2;eval's/A|B/$d{$&}/g;'x$n;s/A|B//g;map{if(/F/){if($r+$p==3){$y+=$p<=>$r}else{$x+=$r<2?$r-$p:$p-$r}$s[($r-1)%4>1?$x--:$x++][$r>1?$y--:$y++]=qw(/ \\)[($p=$r)%2]}else{($r+=2*/-/-1)%=4}}/./g;map{print map{$_||$"}@$_,$/}@s

Tidak terlalu banyak bermain golf

$_=A,%d=<A -BF+AFA+FB- B +AF-BFB-FA+>,$x=2**($n=<>)-2;
eval's/A|B/$d{$&}/g;'x$n;
s/A|B//g;
map{if(/F/){
    if($r+$p==3){$y+=$p<=>$r}else{$x+=$r<2?$r-$p:$p-$r}
        $s[($r-1)%4>1?$x--:$x++][$r>1?$y--:$y++]=qw(/ \\)[($p=$r)%2]
    }else{
        ($r+=2*/-/-1)%=4
    }
}/./g;
map{print map{$_||$"}@$_,$/}@s

Mungkin bisa menurunkannya jika saya lebih memahami Perl. Menggunakan pendekatan sistem Lindenmayer menggunakan aturan produksi yang didefinisikan pada baris 1.


2

APL (Dyalog Unicode) , 90 byte SBCS

⎕∘←¨' +$'r''¨↓1↓∘⍉∘⌽⍣4' /\'[{3|(⊢+⍉)2@(¯1 0+3 1×s÷2)s⊢(¯.5×≢⍵)⊖(2×s←⍴⍵)↑⍵,⍨-⊖⍵}⍣⎕⊢2 2⍴0]

Cobalah online!

2 2⍴0 sebuah matriks 2x2 nol

{ }⍣⎕ masukan N dan terapkan fungsi N kali

⍵,⍨-⊖⍵ menyatukan salinan matriks yang dibalik dan dinegasikan secara vertikal ke kiri matriks

(2×s←⍴⍵)↑pad dengan nol sehingga dimensi (dikenang sebagai s) dua kali argumen

¯.5×≢⍵ putar ke bawah untuk memusatkannya secara vertikal, diapit di antara nol bantalan

2@(¯1 0+3 1×s÷2) Letakkan 2-s di lokasi tertentu - ini adalah garis miring yang menghubungkan antara instance fraktal yang lebih kecil

(⊢+⍉) tambahkan matriks dengan diri yang ditransformasikan

3|modulo 3; kami menggunakan negasi, jadi harap perhatikan bahwa -1≡2 (mod 3) dan -2≡1 (mod 3)

' /\'[ ] gunakan elemen matriks sebagai indeks dalam string ' /\'

1↓∘⍉∘⌽⍣4 potong margin kosong selebar 1 elemen dari semua sisi

terpecah menjadi garis-garis

' +$'⎕r''¨ hapus spasi tambahan dari masing-masing (tantangan ini mengharuskannya)

⎕∘←¨ output masing-masing

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.