Zeichnen Sie die Hilbert-Kurve mit Schrägstrichen

30

Die Hilbert-Kurve ist ein raumfüllendes Fraktal, das als Lindenmayer-System mit folgenden Generationen dargestellt werden kann:
Hilbert-Kurve
Dank http://www.texample.net/tikz/examples/hilbert-curve/ für das Bild.

Tor

Schreiben Sie das kürzestmögliche Programm (in Bytes), das eine positive ganze Zahl n von stdin nimmt und die Hilbert-Kurve n-ter Ordnung mit nur Schrägstrich, Schrägstrich zurück, Leerzeichen und Zeilenumbruch zu stdout zeichnet.

Wenn zum Beispiel der Eingang 1der Ausgang ist, muss er sein

 \
\/

Wenn der Eingang ist, 2muss der Ausgang sein

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

Wenn der Eingang ist, 3muss der Ausgang sein

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

Und so weiter. (Sie sehen besser aus, wenn Sie sie in etwas mit weniger Zeilenabstand einfügen.)

Die Ausgabe sollte keine Zeilenumbrüche über oder unter den äußersten Punkten der Kurve sowie keine nachgestellten Leerzeichen auf den Zeilen enthalten.

Calvins Hobbys
quelle

Antworten:

10

Ruby, 247 230 205 Zeichen

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

Ein ASCII-Turtle-Ansatz unter Verwendung der Lindenmayer-Darstellung ( hier ausprobieren ).

Vielen Dank an @Ventero für das weitere Golfen.

Howard
quelle
Golfen Sie dies ein bisschen mehr, ich hoffe, es macht Ihnen nichts aus: ideone.com/kvcPWT - das .map(&:rstrip)musste hinzugefügt werden, um die "No Trailing Spaces" -Anforderung zu erfüllen.
Ventero
@Ventero Danke. Ich hoffe, es macht Ihnen nichts aus, dass ich Ihre Lösung gewählt habe - Sie können sogar die Klammern um das Kartenargument verwerfen.
Howard
Ah, natürlich! Ich habe auch nur erkannt , dass es möglich ist, die Definition von Inline xund verkürzt die Zuweisung yund d, für insgesamt 205 Zeichen (siehe den gleichen Link wie zuvor).
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()

Dies verwendet einen rekursiven Ansatz, um die Hilbert-Kurve n-ter Ordnung aus der vorherigen Kurve zu konstruieren. Die Kurven werden zum besseren Schneiden und Manipulieren als 2d numpy-Array dargestellt.

Hier sind einige Beispiele:

$ python hilbert.py
2
  /
  \/\
/\   \
 / /\/
 \ \
  \/
$ python hilbert.py
3
       \
     /\/
    /   /\
    \/\ \ \
  /\  / / /
 / /  \/  \/\
 \ \/\  /\   \
\/   / / / /\/
  /\/ /  \ \
  \   \/\ \/
   \/\   \
     / /\/
     \ \
      \/
$ python hilbert.py
4
              /
              \/\
            /\   \
           / / /\/
           \ \ \  /\
         /\/  \/  \ \
        /   /\  /\/ /
        \/\ \ \ \   \/\
      /\  / /  \ \/\   \
     / /  \/ /\/   / /\/
     \ \/\  /   /\/ /   /\
   /\/   /  \/\ \   \/\ \ \
  /   /\/ /\  / / /\  / / /
  \/\ \  / /  \/ / /  \/  \/\
/\   \ \ \ \/\   \ \/\  /\   \
 / /\/  \/   / /\/   / / / /\/
 \ \  /\  /\/  \  /\/ /  \ \
  \/  \ \ \  /\/  \   \/\ \/
    /\/ / / /   /\ \/\   \
    \   \/  \/\ \ \  / /\/
     \/\  /\  / / /  \ \
       / / /  \/  \/\ \/
       \ \ \/\  /\   \
        \/   / / / /\/
          /\/ /  \ \
          \   \/\ \/
           \/\   \
             / /\/
             \ \
              \/
grc
quelle
5

Malsys - 234 221 Zeichen

Ich rieche hier ein paar L-Systeme :) Malsys ist Online-L-System-Interpreter. Dies ist kein ernstzunehmender Eintrag, aber ich fand diese Lösung etwas interessant.

Die Syntax von Malsys eignet sich nicht wirklich zum Golfen, da sie eine Menge langwieriger Stichwörter enthält, aber dennoch recht kurz, lesbar und aussagekräftig ist.

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

Dolmetscher: http://malsys.cz/Process

Golf Version:

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;

Und wie wäre es mit Ascii hexagonalen Gosper-Kurve? :)

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

http://malsys.cz/g/ae5v5vGB

NightElfik
quelle
2

JavaScript (ES6) 313 340

Bearbeiten Einige Zeichen wurden mit sehr schlecht entfernt Methoden entfernt wurden - wie die globale Variable w anstelle eines Rückgabewerts von Funktion H

Konvertieren der x, y-Position in den Abstand d (siehe Wikipedia ) für jedes x, y und Überprüfen, ob die nächstgelegenen Positionen verbunden sind.

Test in der FireFox-Konsole. Eingabe über Popup, Ausgabe über console.log.

Es gibt keine nachgestellten Leerzeichen und keine Zeilenumbrüche über oder unter dem Bild. Aber jede Zeile wird mit einem Zeilenumbruch abgeschlossen. Ich denke, das ist der richtige Weg, um ein ASCII-Kunstbild zu erstellen.

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)
edc65
quelle
Sie können einige Zeichen speichern, indem Sie alertanstelle von verwenden console.log. Sie haben auch ein zusätzliches Leerzeichen nach der forvierten Zeile, und Sie sollten in der Lage sein, diesen letzten Zeilenumbruch loszuwerden.
Bob
@ Bob ja in der Tat kann ich mehr als 15 Zeichen speichern, ich habe aufgegeben zu sehen, dass ich über 300 bin. Ich verwende 'alert' nicht gern, weil das Bild ohne eine Schriftart mit fester Tonhöhe nicht
wiederzuerkennen ist
2

Perl, 270 Zeichen

Super golfen

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

Nicht so viel Golf gespielt

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

Könnte wahrscheinlich mehr Golf spielen, wenn ich Perl besser verstehe. Verwendet einen Lindenmayer-Systemansatz unter Verwendung der in Zeile 1 definierten Produktionsregeln.

tödlich
quelle
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]

Probieren Sie es online!

2 2⍴0 eine 2x2 Matrix von Nullen

{ }⍣⎕ Geben Sie N ein und wenden Sie eine Funktion N-mal an

⍵,⍨-⊖⍵ Verketten Sie links von der Matrix eine vertikal umgekehrte und negierte Kopie von sich

(2×s←⍴⍵)↑Mit Nullen auffüllen, sodass die Dimensionen (die als gespeichert werden s) doppelt so groß sind wie die der Argumente

¯.5×≢⍵ nach unten drehen, um es vertikal zu zentrieren, zwischen den Füllungsnullen eingeklemmt

2@(¯1 0+3 1×s÷2) setze 2-s an bestimmten Stellen - das sind die Verbindungsstriche zwischen kleineren Instanzen des Fraktals

(⊢+⍉) füge die Matrix mit ihrem transponierten Selbst hinzu

3|Modulo 3; Wir haben die Negation verwendet. Bitte beachten Sie, dass -1≡2 (Mod 3) und -2≡1 (Mod 3)

' /\'[ ] Verwenden Sie die Matrixelemente als Indizes in der Zeichenfolge ' /\'

1↓∘⍉∘⌽⍣4 Schneiden Sie den 1-Element-breiten leeren Rand von allen Seiten ab

in Zeilen aufgeteilt

' +$'⎕r''¨ entferne nachfolgende Leerzeichen von jedem (diese Herausforderung erfordert es)

⎕∘←¨ jeweils ausgeben

ngn
quelle