Koch Snowflake - Codegolf

21

Die Koch-Schneeflocke (auch als Koch-Stern und Koch-Insel bekannt) ist eine mathematische Kurve und eine der frühesten beschriebenen fraktalen Kurven. Es basiert auf der Kochschen Kurve, die 1904 in einem Artikel mit dem Titel "Auf einer kontinuierlichen Kurve ohne Tangenten, konstruierbar aus elementarer Geometrie" (französischer Originaltitel: "Sur une courbe continue sans tangente, obtenue par une construction géométrique élémentaire") von der schwedische Mathematiker Helge von Koch.

Bildbeschreibung hier eingeben

Hier sind einige ASCII-Darstellungen verschiedener Iterationen:

n=1
__
\/

n=2
__/\__
\    /
/_  _\
  \/

n=3
      __/\__
      \    /
__/\__/    \__/\__
\                /
/_              _\
  \            /
__/            \__
\                /
/_  __      __  _\
  \/  \    /  \/
      /_  _\
        \/ 

Da die Auflösung der ASCII-Darstellung offensichtlich begrenzt ist, müssen wir die Größe der Schneeflocke für jede Iteration um den Faktor 3 vergrößern, um das zusätzliche Detail zu zeigen.

Schreiben Sie den kürzesten Code, um die Schneeflocke im gleichen Stil für n = 4 auszugeben

Ihr Programm sollte keine Eingaben annehmen.
Ihr Programm sollte die Schneeflocke auf die Konsole schreiben.

Knabberzeug
quelle
Koch-Schneeflocke .. ein Tag .. das ist interessant .. !! .. anscheinend werden Sie weitere Fragen zu diesem Tag abfeuern :)
Aman ZeeK Verma
5
Für eine Antwort zu kurz: wolframalpha.com/input/?i=koch+snowflake+4 : D
Dr. belisarius
1
Sollte die akzeptierte Antwort geändert werden? Es gibt jetzt kürzere Lösungen.
Timwi

Antworten:

2

Python, 338 Bytes

#coding:u8
print u"碜䄎쀠ࢻ﬊翀蝈⼖㗎芰悼컃뚔㓖ᅢ鄒鱖渟犎윽邃淁挢㇌ꎸ⛏偾࿵헝疇颲㬤箁鴩沬饅앎↳\ufaa4軵몳퍋韎巃๧瓠깡未늳蒤ꕴ⁵ᦸ䥝両䣚蟆鼺伍匧䄂앢哪⡈⁙ತ乸ሣ暥ฦꋟ㞨ޯ⿾庾뻛జ⻏燀䲞鷗﫿".encode("utf-16be").decode("zlib")

Nur ein weiterer Unicode-Exploit

laufen bei ideone

SIE
quelle
5
Gut genug, aber das würde die Quelldatei sicherlich länger als 300 Bytes machen.
Timwi
Die Verbindung ist unterbrochen
Chiel ten Brinke
10

Python, 650 612 594 574 Zeichen

n='\n'
S='_a/G\F I\n'
A=dict(zip(S,('III','   ','__/','  G','\  ','F__','   ','III','')))
B=dict(zip(S,('III','   ','\  ',' aF','/a ','  G','   ','III','')))
C=dict(zip(S,('___','aaa','/  ','GII','II\\','  F','   ','III','')))
def T(s):
 a=b=c=d=r=u''
 for k in s:
    a+=A[k];b+=B[k];c+=C[k]
    if k=='I':a=a[:-3]+('II\\'if'a '==d[1:3]else'GII'if' a'==d[:2]else 3*k)
    d=d[3:]
    if k==n:d=c.replace('____','__/F').replace('aaaa','aa  ').replace('/  a','/a  ').replace('a  F','  aF');r+=a+n+b+n+d+n;a=b=c=''
 return r
print T(T(T('__\n\G\n'))).translate({97:95,71:47,73:32,70:92})

Dies funktioniert, indem das Dreieck jedes Mal um den Faktor 3 erweitert wird. Um dies zu tun, müssen wir verfolgen, ob jedes Symbol eine linke oder eine rechte Grenze ist (z. B. /hängt die Art der Erweiterung davon ab, auf welcher Seite /sich das Innere befindet). Wir verwenden verschiedene Symbole für die beiden möglichen Fälle:

_: _, outside on the top
a: _, outside on the bottom
/: /, outside on the left
G: /, outside on the right
\: \, outside on the left
F: \, outside on the right
<space>: inside
I: outside

Die dVariable behandelt den Sonderfall, dass die Erweiterung eines ain der nächsten Zeile in das 3x3-Format erweitert werden muss.

Keith Randall
quelle
+1 für die erste Antwort auf dem Brett. Ich denke, Sie können die doppelten Leerzeichen durch einen Tabulator in der for-Schleife ersetzen. Versuchen Sie auch, wenn k <"C" anstelle von K == "A" usw. zu verwenden. Jetzt muss ich mir Ihren Algorithmus genauer ansehen :)
gnibbler
Können Sie die vielen if-Anweisungen nicht mit einem assoziativen Array entfernen? Und vielleicht können die verketteten Ersetzungsanweisungen mit einem Array verkürzt werden.
Nabb
('acEei',r'_/\\ ')=> ('aecEi','_\/\ ')spart 1 weitere. Vielleicht möchten Sie auch die unicode.translate().
Gnibbler
Dies druckt auch ungefähr 18 Zeilen vor der Schneeflocke, aber ich nehme an, das OP hat nicht spezifiziert, ob etwas anderes als die Schneeflocke gedruckt werden darf.
RomanSt
6

MS-DOS-16-Bit-Computercode: 199 Byte

Dekodieren Sie über diese Site , speichern Sie sie als "koch.com" -Datei und führen Sie sie über die WinXP-Eingabeaufforderung aus.

sCAAxo7ajsKLz/OquF9fulwvvUoBM9u+BADoiQDodgDocwDogADobQDoagDodwCK8TLSs0+I98cHDQrGRwIktAnNIf7GOO5+7MNWAVwBYwFsAXoBgwGJB4DDAsOIN/7D6QQA/suIF/7P6R0A/suAPyB1AogH/suIB8OBw/8AiDfpBgD+x4gX/sM4734Ciu84z30Cis/Dg8UIg8UCgf1WAXLzg+0Mw07/dgB0GV/o9v/o5v/o8P/o3f/o2v/o5//o1//o4f9Gww==

Aktualisieren

Hier ist eine leicht zu lesende Assembler-Version:

  ; L-System Description
  ;
  ; Alphabet : F
  ; Constants : +, -
  ; Axiom : F++F++F
  ; Production rules: F -> F-F++F-F 
  ;
  ; Register usage:
  ;                             _        _
  ; bp = direction: 0 = ->, 1 = /|, 2 = |\, 3 = <-, 4 = |/_, 5 = _\|
  ; cl = min y, ch = max y
  ; bl = x (unsigned)
  ; bh = y (signed)
  ; si = max level

  ; clear data
  mov al,20h
  add dh,al
  mov ds,dx
  mov es,dx
  mov cx,di
  rep stosb
  mov ax,'__'
  mov dx,'/\'

  ; initialise variables
  mov bp,Direction0
  xor bx,bx
  mov si,4

  call MoveForward
  call TurnRight
  call TurnRight
  call MoveForward
  call TurnRight
  call TurnRight
  call MoveForward

  mov dh,cl
  xor dl,dl
  mov bl,79
OutputLoop:
  mov bh,dh
  mov w [bx],0a0dh
  mov b [bx+2],24h
  mov ah,9
  int 21h
  inc dh
  cmp dh,ch
  jle OutputLoop  
  ret

Direction0:
  dw MoveRight
  dw MoveUpRight
  dw MoveUpLeft
  dw MoveLeft
  dw MoveDownLeft
  dw MoveDownRight
Direction6:

MoveRight:
  mov w [bx],ax
  add bl,2
  ret

MoveUpRight:
  mov b [bx],dh
  inc bl
  jmp DecBHCheckY

MoveUpLeft:
  dec bl
  mov b [bx],dl
DecBHCheckY:  
  dec bh
  jmp CheckY

MoveLeft:
  dec bl  
  cmp b [bx],20h
  jne MoveLeftAgain
  mov [bx],al
MoveLeftAgain:
  dec bl  
  mov [bx],al
  ret

MoveDownLeft:
  add bx,255
  mov b [bx],dh
  jmp CheckY

MoveDownRight:
  inc bh
  mov b [bx],dl
  inc bl

CheckY:
  cmp bh,ch
  jle NoMaxChange
  mov ch,bh
NoMaxChange:  
  cmp bh,cl
  jge NoMinChange
  mov cl,bh
NoMinChange:  
  ret

TurnRight:
  add bp,8

TurnLeft:
  add bp,2

  cmp bp,Direction6
  jb ret
  sub bp,12
  ret

MoveForward:
  dec si
  push [bp]
  jz DontRecurse
  pop di
  call MoveForward
  call TurnLeft
  call MoveForward
  call TurnRight
  call TurnRight
  call MoveForward
  call TurnLeft
  call MoveForward
DontRecurse:
  inc si
  ret
Skizz
quelle
Absolute Magie :), bitte helfen Sie mir, dies zu verstehen (zumindest einen Link zu dem, was Sie getan haben)
Aman ZeeK Verma
@Aman: Es verwendet eine L-Systembeschreibung der Koch-Kurve, um die Ausgabe zu zeichnen. Der Detaillierungsgrad wird im SI-Register festgelegt, obwohl die Größe auf 252 Zeichen pro Zeile begrenzt ist. Sie müssen den Druckcode ändern, um Zeilen zu erhalten, die länger als 79 Zeichen sind (dh ändern Sie, wo die Zeichen '\ n $' geschrieben werden).
Skizz
kann auch "scAA...w==".decode("base64")zum Dekodieren in Python2 verwendet werden (funktioniert nicht für Python3)
gnibbler
+1 jetzt, da ich eine Windows-Maschine habe, auf der ich sie ausführen kann. Gibt es eine Chance, dass Sie eine ASM-Version hinzufügen können?
Knabberzeug
2
@mellamokb: err, weil der gesamte Quellcode vielleicht verfügbar ist?
Skizz
4

Perl, 176 175 Bytes

Dies als separate Antwort zu posten, da eine binäre Quelldatei verwendet wird, die vielleicht ein bisschen betrügerisch ist. Aber wenn man bedenkt, dass es immer noch Perl- Quellcode ist, finde ich es bemerkenswert, dass es die MS-DOS- Maschinencodelösung schlägt !

Quelle als Base64-codiert

JF89IsLApwag0dhnMmAmMEcGIAcGQNHYwsDRFLsQ0djCwKcGoNHYwsDRFDdbECYwcRUxe1DCwNEUuxDR2
CI7c14uXiR4PW9yZCQmOyQieCgkeD4+MykucXcoXCAvXyBfXy8gXC8gX18gX1wgLyBfXy9cX18pWyR4Jj
ddXmVnO3NeLnsyN31eJF89cmV2ZXJzZSQmO3l+L1xcflxcL347cHJpbnQkJi4kXy4kL15lZw==

Etwas lesbarer

Ersetzen Sie alle Instanzen von /<[0-9a-f]+>/durch die relevanten Binärdaten:

# Raw data!
$_="<c2c0a706a0d1d86732602630470620070640d1d8c2c0d114bb10d1d8c2>".
   "<c0a706a0d1d8c2c0d114375b1026307115317b50c2c0d114bb10d1d8>";

# Decode left half of the snowflake (without newlines)
s^.^$x=ord$&;$"x($x>>3).qw(\ /_ __/ \/ __ _\ / __/\__)[$x&7]^eg;

# Reconstruct the right half and the newlines
s^.{27}^$_=reverse$&;y~/\\~\\/~;print$&.$_.$/^eg

In dieser Version ist die Schneeflocke folgendermaßen codiert:

  • Die 8 Bits in jedem Byte sind folgendermaßen aufgeteilt:

    +---+---+---+---+---+---+---+---+
    |      5 bits       |   3 bits  |
    +---+---+---+---+---+---+---+---+
              R               C
    
  • Rkodiert eine Reihe von Leerzeichen. Die längste Folge ist 27 Zeichen, sodass alle Folgen in 5 Bits passen.

  • Ccodiert eine Folge von Zeichen, die einfach im Literal-Array nachgeschlagen werden. (Früher hatte ich hier etwas verrücktere Codierungen, in denen das Array nur enthalten war / \ _, aber der zum Decodieren erforderliche Perl-Code war länger ...)

  • Ich habe das Glück , dass die binären Daten enthalten keine "/ 'oder \das würde zu entkommen muß. Das habe ich nicht geplant. Aber selbst wenn dies der Fall wäre, hätte ich wahrscheinlich einfach die Reihenfolge der Elemente im Array ändern können, um dies zu beheben.

  • Es ist erstaunlich, wie einfach diese Lösung im Vergleich zu den Dutzenden anderen Lösungen ist, die ich durchlaufen habe, bevor ich darauf gekommen bin. Ich habe mit vielen verschiedenen bitweisen Codierungen experimentiert, die komplexer sind als diese, und es ist mir nie aufgefallen, dass eine einfachere es wert sein könnte, einfach weil der Perl-Code zum Decodieren kürzer wäre. Ich habe auch versucht, Wiederholungen in den Daten mit variabler Interpolation zu komprimieren (siehe die andere Antwort), aber mit der neuesten Version, die keine Zeichen mehr erhält.

Timwi
quelle
3

Python, 284

for s in "eJyVkNENACEIQ/+dgg1YiIT9tzgENRyWXM4/pH1tIMJPlUezIiGwMoNgE5SzQvzRBq52Ebce6cr0aefbt7NjHeNEzC9OAalADh0V3gK35QWPeiXIFHKH8seFfh1zlQB6bjxXIeB9ACWRVwo=".decode('base64').decode('zlib').split('\n'):print s+'  '*(27-len(s))+'\\'.join([c.replace('\\','/')for c in s[::-1].split('/')])

Mit etwas mehr Leerzeichen:

for s in "eJyVkNENACEIQ/+dgg1YiIT9tzgENRyWXM4/pH1tIMJPlUezIiGwMoNgE5SzQvzRBq52Ebce6cr0aefbt7NjHeNEzC9OAalADh0V3gK35QWPeiXIFHKH8seFfh1zlQB6bjxXIeB9ACWRVwo=".decode('base64').decode('zlib').split('\n'):
  print s + '  '*(27-len(s)) + '\\'.join([c.replace('\\','/') for c in s[::-1].split('/')])

Die linke Seite ist komprimiert; Die rechte Seite wird von der linken Seite wiedergegeben.

RomanSt
quelle
3

Perl, 224 223 Zeichen

use MIME::Base64;$_=decode_base64 wsCnBqDR2GcyYCYwRwYgBwZA0djCwNEUuxDR2MLApwag0djCwNEUN1sQJjBxFTF7UMLA0RS7ENHY;s^.^$x=ord$&;$"x($x>>3).qw(\ /_ __/ \/ __ _\ / __/\__)[$x&7]^eg;s^.{27}^$_=reverse$&;y~/\\~\\/~;print$&.$_.$/^eg

Etwas lesbarer

use MIME::Base64;

# raw binary data in base-64-encoded form as a bareword
$_=decode_base64
    wsCnBqDR2GcyYCYwRwYgBwZA0djCwNEUuxDR2MLApwag0djCwNEUN1sQJjBxFTF7UMLA0RS7ENHY;

# Decode left half of the snowflake (without newlines)
s^.^$x=ord$&;$"x($x>>3).qw(\ /_ __/ \/ __ _\ / __/\__)[$x&7]^eg;

# Reconstruct the right half and the newlines
s^.{27}^$_=reverse$&;y~/\\~\\/~;print$&.$_.$/^eg

Wie es funktioniert

Eine Erklärung, wie es funktioniert, finden Sie in der anderen Antwort, in der ich dasselbe in binärer Form poste . Es tut mir wirklich leid, dass ich die Koch-Schneeflocke nicht generiere , sondern nur komprimiere ...

Vorherige Versionen

  • (359) Codiert die gesamte Schneeflocke anstatt nur die linke Hälfte. Leerzeichen wurden in die Bitcodierung einbezogen; noch keine lauflänge Verwendete mehrere interpolierte Variablen plus ein @_Array, auf das mit zugegriffen wurde s/\d/$_[$&]/eg. Zeilenumbrüche wurden als codiert !.

  • (289) Erste Version, die nur die linke Hälfte der Schneeflocke codierte.

  • (267) Erste Version, die Lauflängencodierung für die Leerzeichen verwendete.

  • (266) Wechseln ' 'zu $".

  • (224) Radikal unterschiedliche Komprimierung, kodiert als base-64. (Entspricht jetzt der Binärversion .)

  • (223) Es wurde mir klar, dass ich den Abdruck in die letzte Subst legen und so ein Semikolon speichern kann.

Timwi
quelle