Eğik çizgileri kullanarak Hilbert eğrisini çizin


30

Hilbert eğrisi bir şekilde temsil edilebilir bir boşluk doldurma fraktal olan Lindenmayer sistemiyle başarılı nesiller o böyle görünüm:
Hilbert eğrisi
için teşekkür http://www.texample.net/tikz/examples/hilbert-curve/ görüntü için.

Hedef

Stdin'den pozitif bir tamsayı n alan ve mümkün olan en kısa programı (bayt cinsinden) yazın ve sadece birinci eğik çizgiyi, geriye eğik çizgiyi, boşluğu ve yeni satırı kullanarak ilk sıradaki Hilbert eğrisini çizmeye çekin.

Örneğin, giriş 1çıkış ise

 \
\/

Girdi ise 2çıktı olmalıdır.

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

Girdi ise 3çıktı olmalıdır.

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

Ve bunun gibi. (Daha az satır aralığı olan bir şeye yapıştırırsanız daha iyi görünürler.)

Çıktı, eğrinin uç noktalarının üstünde ya da altında yeni çizgiler ya da herhangi bir çizgi üzerinde takip eden boşluklar içermemelidir.

Yanıtlar:


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

Lindenmayer temsilini kullanan bir ASCII-kaplumbağa yaklaşımı ( burada deneyin ).

Büyük , biraz daha golf oynadığı için @ Ventero'ya teşekkür ederim .


Bu biraz daha Golf , umursamıyorum: ideone.com/kvcPWT - .map(&:rstrip)"boşluk yok" şartı yerine getirmek için eklenmesi gerekiyordu.
Ventero

@Ventero Teşekkürler. Umarım çözümünüzü almamın sakıncası yoktur - harita argümanının etrafındaki parantezleri bile atabilirsiniz.
Howard,

Ah, elbette! Ben de sadece tanımını satır içi mümkün olduğunu fark etti xve atama kısaltmak yve d(daha önce olduğu gibi aynı bağlantıya bakınız) 205 karakterden olmak üzere toplam.
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()

Bu, ilk sıradaki Hilbert eğrisini bir önceki eğriden çıkarmak için özyinelemeli bir yaklaşım kullanır. Eğriler daha iyi dilimleme ve manipülasyon için 2d numpy dizisi olarak temsil edilir.

İşte bazı örnekler:

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

5

Malsys - 234 221 karakter

Burada bazı L sistemlerini kokluyorum :) Malsys çevrimiçi L sistemi tercümanıdır. Bu gerçekten ciddi bir giriş değil ama bu çözümün biraz ilginç olduğunu hissettim.

Çok sayıda uzun anahtar kelime içerdiği için Malsys'in sözdizimi golf oynamak için iyi değil ama yine de oldukça kısa, okunaklı ve etkileyici.

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

Tercüman: http://malsys.cz/Process

Golf versiyonu:

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;

Ve Ascii altıgen Gosper eğrisi hakkında nasıl? :)

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

http://malsys.cz/g/ae5v5vGB


2

JavaScript (ES6) 313 340

Düzenleme Bazı karakterler gerçekten kötü uygulamalar kullanılarak kaldırıldı - H fonksiyonundan bir dönüş değeri yerine global değişken w gibi

X, y konumlarının her x, y için d mesafesine ( Wikipedia'ya bakınız ) dönüştürülmesi ve en yakın konumların bağlı olup olmadığının doğrulanması,

FireFox konsolunda test edin. Açılır pencereden giriş, konsol çıkışından çıkış.

Görüntünün üzerinde veya altında iz bırakan boşluk yok ve yeni satır yok. Ancak her satır yeni bir satırla sonlandırılıyor, Ascii sanat imajı yaratmanın doğru yolu olduğunu düşünüyorum.

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)

Sen kullanarak bazı karakterleri kurtarabilecek alertyerine console.log. Ayrıca fordördüncü satırdan sonra fazladan bir alanınız var ve bu son satır sonundan kurtulabilmelisiniz.
Bob,

@Bob evet aslında 15 karakterden daha fazlasını kaydedebilirim, yine de 300'den fazla olduğumu görmekten vazgeçtim. '
Alert

2

Perl, 270 Karakter

Süper 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

Çok golf değil

$_=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

Perl'i daha iyi anlasaydım muhtemelen golf oynayabilirdi. 1. satırda tanımlanan üretim kurallarını kullanarak Lindenmayer sistem yaklaşımını kullanır.


2

APL (Dyalog Unicode) , 90 baytlık SBCS

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

Çevrimiçi deneyin!

2 2⍴0 2x2 sıfır matris

{ }⍣⎕ N girişi ve N kere bir fonksiyon uygulayın

⍵,⍨-⊖⍵ matrisin soluna dikey olarak ters çevrilmiş ve olumsuz sayılan bir kopyasını birleştirmek

(2×s←⍴⍵)↑Ölçüler (hatırlananlar s) iki argümanın iki katı olacak şekilde

¯.5×≢⍵ dikey olarak ortalamak için aşağı doğru döndürün, doldurma sıfırları arasında gezdirin

2@(¯1 0+3 1×s÷2) belirli yerlere 2-s koy - bunlar fraktalın küçük örnekleri arasındaki bağlantı eğik çizgileridir.

(⊢+⍉) matrisi kendi aktarılmış benliği ile ekleyin

3|modulo3; olumsuzlama kullandık, lütfen -1≡2 (mod 3) ve -2≡1 (mod 3)

' /\'[ ] matris öğelerini dizgede indeks olarak kullanın ' /\'

1↓∘⍉∘⌽⍣4 1 eleman çapında boş kenar boşluğunu her taraftan düzeltin

çizgilere ayrılmak

' +$'⎕r''¨ her birini takip eden boşlukları kaldır (bu zorluk onu gerektirir)

⎕∘←¨ her biri çıktı

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.