Koch Snowflake - codegolf

21

The Koch snowflake (juga dikenal sebagai bintang Koch dan pulau Koch) adalah kurva matematika dan salah satu kurva fraktal awal telah dijelaskan. Hal ini didasarkan pada kurva Koch, yang muncul dalam makalah 1904 berjudul "Pada kurva kontinu tanpa garis singgung, dapat dibangun dari geometri dasar" (judul Prancis asli: "Sur une courbe melanjutkan sans tangente, lihat par une konstruksi géométrique élémentaire") oleh matematikawan Swedia Helge von Koch.

masukkan deskripsi gambar di sini

Berikut adalah beberapa representasi ascii dari berbagai iterasi:

n=1
__
\/

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

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

Karena jelas ada batas untuk resolusi representasi ascii, kita harus memperbesar ukuran kepingan salju dengan faktor 3 untuk setiap iterasi untuk menunjukkan detail ekstra.

Tulis kode terpendek untuk menampilkan kepingan salju dengan gaya yang sama untuk n = 4

Program Anda seharusnya tidak mengambil input apa pun.
Program Anda harus menulis kepingan salju ke konsol.

gnibbler
sumber
Koch-snowflake .. sebuah tag .. itu menarik .. !! .. tampaknya Anda akan mengajukan lebih banyak pertanyaan pada tag ini :)
Aman ZeeK Verma
5
Terlalu pendek untuk dijawab: wolframalpha.com/input/?i=koch+snowflake+4 : D
Dr. belisarius
1
Haruskah jawaban yang diterima diubah? Ada solusi yang lebih pendek sekarang.
Timwi

Jawaban:

2

Python, 338 byte

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

Hanya eksploitasi unicode lain

lari pada ideone

KAMU
sumber
5
Cukup adil, tapi pasti itu akan membuat file sumber lebih dari 300 byte.
Timwi
tautannya rusak
Chiel ten Brinke
10

Python, 650 612 594 574 karakter

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

Ini bekerja dengan memperluas segitiga dengan faktor 3 setiap kali. Untuk melakukan itu, kita perlu melacak apakah setiap simbol adalah batas kiri atau kanan (misalnya bagaimana /diperluas tergantung pada sisi mana yang /merupakan bagian dalam). Kami menggunakan simbol yang berbeda untuk dua kemungkinan kasus, sebagai berikut:

_: _, 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

The dvariabel menangani kasus khusus di mana perluasan suatu akebutuhan untuk memperluas ke 3x3 di baris berikutnya.

Keith Randall
sumber
+1 untuk mendapatkan jawaban pertama di papan tulis. Saya pikir Anda dapat mengganti spasi ganda dengan tab di loop for. Juga coba gunakan jika k <"C" bukan K == "A" dll. Sekarang saya harus melihat lebih dekat pada algoritma Anda :)
gnibbler
Tidak bisakah Anda menghapus banyak jika pernyataan dengan array asosiatif? Dan mungkin pernyataan ganti dirantai dapat disingkat dengan array.
Nabb
('acEei',r'_/\\ ')=> ('aecEi','_\/\ ')menyimpan 1 lagi. Anda mungkin juga ingin memeriksa unicode.translate().
gnibbler
Ini juga mencetak sekitar 18 baris sebelum kepingan salju, tapi saya kira OP tidak menentukan apakah sesuatu lainnya dari kepingan salju dapat dicetak.
RomanSt
6

Kode mesin MS-DOS 16 bit: 199 byte

Decode menggunakan situs ini , simpan sebagai file 'koch.com' dan jalankan dari command prompt WinXP.

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

Memperbarui

Berikut ini adalah versi assembler yang mudah dibaca:

  ; 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
Mendesis
sumber
Abolute magic :), tolong bantu saya memahami ini (minimal sediakan tautan pada apa yang Anda lakukan)
Aman ZeeK Verma
@ Aman: Ini menggunakan deskripsi L-sistem dari kurva Koch untuk menggambar output. Tingkat detail diatur dalam register SI meskipun ukurannya dibatasi hingga 252 karakter per baris. Anda harus mengubah kode pencetakan untuk mendapatkan garis yang lebih panjang dari 79 karakter (mis. Ubah tempat ia menulis karakter '\ n $').
Skizz
juga dapat digunakan "scAA...w==".decode("base64")untuk mendekode di Python2 (tidak berfungsi untuk Python3)
gnibbler
+1 sekarang saya memiliki mesin windows untuk menjalankannya. Apakah Anda bisa memasukkan versi asm?
gnibbler
2
@mellamokb: err, karena semua kode sumber mungkin tersedia?
Skizz
4

Perl, 176 175 byte

Posting ini sebagai jawaban terpisah karena menggunakan file sumber biner, yang mungkin agak curang. Tapi mengingat itu masih kode sumber Perl , saya pikir itu luar biasa bahwa itu mengalahkan solusi kode mesin MS-DOS !

Sumber sebagai base64-encoded

JF89IsLApwag0dhnMmAmMEcGIAcGQNHYwsDRFLsQ0djCwKcGoNHYwsDRFDdbECYwcRUxe1DCwNEUuxDR2
CI7c14uXiR4PW9yZCQmOyQieCgkeD4+MykucXcoXCAvXyBfXy8gXC8gX18gX1wgLyBfXy9cX18pWyR4Jj
ddXmVnO3NeLnsyN31eJF89cmV2ZXJzZSQmO3l+L1xcflxcL347cHJpbnQkJi4kXy4kL15lZw==

Agak lebih mudah dibaca

Ganti semua instance /<[0-9a-f]+>/dengan data biner yang relevan:

# 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

Dalam versi ini, kepingan salju dikodekan dengan cara berikut:

  • 8 bit dalam setiap byte dibagi seperti ini:

    +---+---+---+---+---+---+---+---+
    |      5 bits       |   3 bits  |
    +---+---+---+---+---+---+---+---+
              R               C
    
  • Rmengkodekan serangkaian spasi. Run terpanjang adalah 27 karakter, jadi semua run masuk ke dalam 5 bit.

  • Cmengkodekan urutan karakter yang hanya dilihat dalam array literal. (Dulu saya memiliki penyandian sedikit lebih gila di sini di mana array hanya berisi / \ _, tetapi kode Perl yang diperlukan untuk memecahkan kode itu lebih lama ...)

  • Saya beruntung bahwa data biner tidak mengandung "/ 'atau \yang perlu melarikan diri. Saya tidak berencana untuk ini. Tetapi bahkan jika itu terjadi, saya mungkin bisa saja mengubah urutan item dalam array untuk memperbaikinya.

  • Sungguh menakjubkan betapa sederhananya solusi ini dibandingkan dengan puluhan solusi lain yang saya lalui sebelum saya menemukan ini. Saya bereksperimen dengan banyak pengkodean bitwise berbeda yang lebih kompleks daripada yang ini, dan tidak pernah terpikir oleh saya bahwa yang lebih sederhana mungkin sepadan hanya karena kode Perl untuk memecahkan kode akan lebih pendek. Saya juga mencoba untuk mengompresi pengulangan dalam data menggunakan interpolasi variabel (lihat jawaban lain), tetapi dengan versi terbaru yang tidak mendapatkan karakter apa pun lagi.

Timwi
sumber
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('/')])

Dengan spasi lebih sedikit:

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('/')])

Sisi kiri dikompresi; sisi kanan direproduksi dari sisi kiri.

RomanSt
sumber
3

Perl, 224 223 karakter

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

Agak lebih mudah dibaca

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

Bagaimana itu bekerja

Untuk penjelasan tentang cara kerjanya, lihat jawaban lain di mana saya memposting yang sama dalam biner . Saya benar-benar menyesal bahwa saya tidak benar-benar menghasilkan kepingan salju Koch, hanya mengompresnya ...

Versi sebelumnya

  • (359) Menyandikan seluruh kepingan salju alih-alih hanya setengah yang tersisa. Spasi dimasukkan dalam pengkodean bit; belum ada run-length. Digunakan beberapa variabel interpolasi ditambah @_array yang diakses menggunakan s/\d/$_[$&]/eg. Baris baru dikodekan sebagai !.

  • (289) Versi pertama yang disandikan hanya setengah dari kepingan salju.

  • (267) Versi pertama yang menggunakan pengkodean run-length untuk spasi.

  • (266) Ubah ' 'ke $".

  • (224) Kompresi yang sangat berbeda, dikodekan sebagai basis-64. (Sekarang setara dengan versi biner .)

  • (223) Menyadari bahwa saya dapat meletakkan cetakan di dalam subtitle terakhir dan dengan demikian menyimpan tanda koma.

Timwi
sumber