Koch Snowflake - codegolf


21

Koch เกล็ดหิมะ (ที่เรียกกันว่าดาว Koch และเกาะโคช์) เป็นเส้นโค้งทางคณิตศาสตร์และเป็นหนึ่งในโค้งเศษส่วนที่เก่าแก่ที่สุดได้รับการอธิบาย มันขึ้นอยู่กับเส้นโค้ง Koch ซึ่งปรากฏในกระดาษ 1904 หัวข้อ "ในโค้งอย่างต่อเนื่องโดยไม่ต้องเสียสละสร้างจากเรขาคณิตเบื้องต้น" (ต้นฉบับภาษาฝรั่งเศสชื่อ: "Sur une courbe ยังคง sang tangente, obtenue พาร์ une ก่อสร้างgéométriqueélémentaire") โดย นักคณิตศาสตร์ชาวสวีเดน Helge von Koch

ป้อนคำอธิบายรูปภาพที่นี่

นี่คือบางส่วนที่เป็นตัวแทนของการทำซ้ำต่างๆ:

n=1
__
\/

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

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

เนื่องจากมีการจำกัดความคมชัดของการเป็นตัวแทน Ascii อย่างชัดเจนเราจึงต้องขยายขนาดของเกล็ดหิมะด้วยปัจจัย 3 สำหรับการวนซ้ำแต่ละครั้งเพื่อแสดงรายละเอียดเพิ่มเติม

เขียนรหัสที่สั้นที่สุดเพื่อเอาท์พุทเกล็ดหิมะในรูปแบบเดียวกันสำหรับ n = 4

โปรแกรมของคุณไม่ควรรับอินพุตใด ๆ
โปรแกรมของคุณควรเขียนเกล็ดหิมะลงบนคอนโซล


แท็ก Koch-snowflake ..a .. ที่น่าสนใจ .. !! .. ดูเหมือนว่าคุณจะยิงคำถามเพิ่มเติมเกี่ยวกับแท็กนี้ :)
Aman ZeeK Verma

5
สั้นเกินไปสำหรับคำตอบ: wolframalpha.com/input/?i=koch+snowflake+4 : D
Dr. belisarius

1
คำตอบที่ยอมรับควรเปลี่ยนไปหรือไม่? ตอนนี้มีวิธีแก้ปัญหาที่สั้นกว่า
Timwi

คำตอบ:


2

Python ขนาด 338 ไบต์

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

อีกหนึ่งช่องโหว่ใช้ประโยชน์ Unicode

ทำงานที่ideone


5
ยุติธรรมเพียงพอ แต่แน่นอนว่าจะทำให้ไฟล์ต้นฉบับยาวเกิน 300 ไบต์
Timwi

ลิงก์เสียหาย
Chiel ten Brinke

10

Python 650 612 594 574 ตัวอักษร

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

วิธีนี้ใช้งานได้โดยการขยายสามเหลี่ยมเป็น 3 เท่าในแต่ละครั้ง ในการทำเช่นนั้นเราจำเป็นต้องติดตามว่าสัญลักษณ์แต่ละอันนั้นเป็นขอบเขตด้านซ้ายหรือขวา (เช่นการ/ขยายตัวขึ้นอยู่กับด้านของด้าน/ใน) เราใช้สัญลักษณ์ที่แตกต่างกันสำหรับสองกรณีที่เป็นไปได้ดังนี้:

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

dตัวแปรจัดการกรณีพิเศษที่การขยายตัวของนั้นaความต้องการที่จะขยายเข้าไปใน 3x3 ในแถวถัดไป


+1 เพื่อรับคำตอบแรกบนกระดาน ฉันคิดว่าคุณสามารถแทนที่ช่องว่างสองครั้งด้วยแท็บในการวนซ้ำ ลองใช้ถ้า k <"C" แทน K == "A" เป็นต้นตอนนี้ฉันจะต้องดูอัลกอริธึมของคุณให้ละเอียดยิ่งขึ้น :)
gnibbler

คุณไม่สามารถลบคำสั่งจำนวนมากหากมีอาเรย์แบบเชื่อมโยงได้หรือไม่ และบางทีประโยคคำสั่งแทนที่ที่ถูกโยงโซ่สามารถสั้นลงด้วยอาร์เรย์
Nabb

('acEei',r'_/\\ ')=> ('aecEi','_\/\ ')ประหยัดอีก 1 unicode.translate()นอกจากนี้คุณยังอาจต้องการที่จะตรวจสอบ
gnibbler

นี้ยังพิมพ์ประมาณ 18 บรรทัดใหม่ก่อนเกล็ดหิมะ แต่ฉันคิดว่า OP ไม่ได้ระบุว่าอะไรอื่น ๆกว่าเกล็ดหิมะอาจจะพิมพ์
RomanSt

6

รหัสเครื่อง MS-DOS 16 บิต: 199 ไบต์

ถอดรหัสโดยใช้เว็บไซต์นี้บันทึกเป็นไฟล์ 'koch.com' และดำเนินการจากพรอมต์คำสั่ง 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==

ปรับปรุง

นี่คือแอสเซมเบลอร์เวอร์ชั่นที่อ่านง่าย:

  ; 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

ยกเลิกเวทมนตร์ :) โปรดช่วยฉันเข้าใจสิ่งนี้ (atleast ให้ลิงก์ในสิ่งที่คุณทำ)
Aman ZeeK Verma

@Aman: ใช้คำอธิบายระบบ L ของเส้นโค้ง Koch เพื่อวาดผลลัพธ์ ระดับรายละเอียดถูกตั้งค่าในการลงทะเบียน SI แม้ว่าขนาดจะ จำกัด อยู่ที่ 252 อักขระต่อบรรทัด คุณจะต้องแก้ไขรหัสการพิมพ์เพื่อให้ได้บรรทัดที่ยาวเกิน 79 ตัวอักษร (เช่นการเปลี่ยนแปลงที่จะเขียนอักขระ '\ n $')
Skizz

ยังสามารถใช้"scAA...w==".decode("base64")เพื่อถอดรหัสใน Python2 (ไม่ทำงานสำหรับ Python3)
gnibbler

+1 ทันทีที่ฉันมีเครื่องที่เปิดใช้ Windows โอกาสใดที่คุณสามารถรวมเวอร์ชัน asm
gnibbler

2
@mellamokb: เอ่อเพราะซอร์สโค้ดทั้งหมดมีอยู่บ้างมั้ย
Skizz

4

Perl, 176 175 ไบต์

การโพสต์สิ่งนี้เป็นคำตอบที่แยกต่างหากเพราะมันใช้ไฟล์ต้นฉบับไบนารีซึ่งอาจจะเป็นบิตที่โกง แต่เมื่อพิจารณาว่ามันยังคงเป็นซอร์สโค้ดของ Perl ฉันคิดว่ามันน่าทึ่งที่มันชนะการแก้ปัญหาของรหัสเครื่อง MS-DOS !

แหล่งที่มาเป็นเข้ารหัส 64

JF89IsLApwag0dhnMmAmMEcGIAcGQNHYwsDRFLsQ0djCwKcGoNHYwsDRFDdbECYwcRUxe1DCwNEUuxDR2
CI7c14uXiR4PW9yZCQmOyQieCgkeD4+MykucXcoXCAvXyBfXy8gXC8gX18gX1wgLyBfXy9cX18pWyR4Jj
ddXmVnO3NeLnsyN31eJF89cmV2ZXJzZSQmO3l+L1xcflxcL347cHJpbnQkJi4kXy4kL15lZw==

ค่อนข้างอ่านได้มากขึ้น

แทนที่อินสแตนซ์ทั้งหมดของ/<[0-9a-f]+>/ด้วยข้อมูลไบนารีที่เกี่ยวข้อง:

# 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

ในรุ่นนี้เกล็ดหิมะถูกเข้ารหัสด้วยวิธีต่อไปนี้:

  • 8 บิตในแต่ละไบต์จะถูกแบ่งออกดังนี้:

    +---+---+---+---+---+---+---+---+
    |      5 bits       |   3 bits  |
    +---+---+---+---+---+---+---+---+
              R               C
    
  • Rเข้ารหัสการทำงานของช่องว่าง ระยะเวลาที่ยาวที่สุดคือ 27 ตัวอักษรดังนั้นการวิ่งทั้งหมดจะพอดีกับ 5 บิต

  • Cเข้ารหัสลำดับของอักขระที่ถูกค้นหาในอาเรย์ตัวอักษร (ฉันเคยมีการเข้ารหัส crazier เล็กน้อยที่นี่ที่อาร์เรย์มีเพียง/ \ _แต่รหัส Perl ที่จำเป็นในการถอดรหัสมันอีกต่อไป ... )

  • ฉันโชคดีที่ข้อมูลเลขฐานสองไม่มี"/ 'หรือ\ต้องหนีไป ฉันไม่ได้วางแผนสำหรับสิ่งนี้ แต่ถึงแม้ว่าจะเป็นเช่นนั้นฉันก็อาจจะแค่เปลี่ยนลำดับของรายการในอาเรย์เพื่อแก้ไข

  • มันวิเศษมากที่วิธีแก้ปัญหานี้ง่ายเมื่อเทียบกับโซลูชั่นอื่น ๆ นับสิบที่ฉันได้ทำมาก่อนที่ฉันจะได้สิ่งนี้ ฉันทดลองกับการเข้ารหัสบิตทริกที่แตกต่างกันมากมายที่ซับซ้อนกว่าอันนี้และมันก็ไม่เคยเกิดขึ้นกับฉันว่าอันที่เรียบง่ายอาจจะคุ้มค่าเพราะรหัส Perl ในการถอดรหัสมันจะสั้นกว่า ฉันยังพยายามบีบอัดข้อมูลซ้ำในข้อมูลโดยใช้การแก้ไขตัวแปร (ดูคำตอบอื่น ๆ ) แต่ด้วยเวอร์ชันล่าสุดที่ไม่ได้รับตัวอักษรอีกต่อไป


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

ด้วยพื้นที่ว่างเพิ่มเติมอีกเล็กน้อย:

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

ด้านซ้ายถูกบีบอัด ด้านขวาทำซ้ำจากด้านซ้าย


3

Perl, 224 223 ตัวอักษร

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

ค่อนข้างอ่านได้มากขึ้น

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

มันทำงานอย่างไร

สำหรับคำอธิบายของวิธีการทำงานให้ดูคำตอบอื่น ๆ ที่ผมโพสต์เดียวกันในไบนารี ฉันเสียใจจริงๆที่ฉันไม่ได้สร้างเกล็ดหิมะ Koch เพียงแค่บีบอัดมัน ...

รุ่นก่อนหน้า

  • (359)เข้ารหัสเกล็ดหิมะทั้งหมดแทนที่จะเป็นครึ่งซ้าย ช่องว่างถูกรวมอยู่ในการเข้ารหัสบิต ยังไม่มีความยาว มือสองตัวแปรหยันหลายบวกอาร์เรย์ซึ่งเข้าถึงได้โดยใช้@_ การขึ้นบรรทัดใหม่ถูกเข้ารหัสเป็นs/\d/$_[$&]/eg!

  • (289)รุ่นแรกที่เข้ารหัสเฉพาะครึ่งซ้ายของเกล็ดหิมะ

  • (267)รุ่นแรกที่ใช้การเข้ารหัสความยาววิ่งสำหรับช่องว่าง

  • (266)เปลี่ยนไป' '$"

  • (224)การบีบอัดที่แตกต่างอย่างสิ้นเชิงเข้ารหัสเป็น base-64 (ตอนนี้เทียบเท่ากับรุ่นไบนารี )

  • (223)ตระหนักว่าฉันสามารถวางการพิมพ์ไว้ในส่วนย่อยสุดท้ายและดังนั้นจึงบันทึกอัฒภาค

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.