Bông tuyết Koch - cá tuyết


21

Các Koch bông tuyết (còn gọi là ngôi sao Koch và đảo Koch) là một đường cong toán học và là một trong các đường cong fractal sớm nhất đã được mô tả. Nó dựa trên đường cong Koch, xuất hiện trong một bài báo năm 1904 có tiêu đề "Trên một đường cong liên tục không có tiếp tuyến, có thể xây dựng từ hình học cơ bản" (tựa gốc tiếng Pháp: "Sur une Majbe tiếp tục sans tangente, obtenue par une xây dựng géométrique élémentaire") nhà toán học người Thụy Điển Helge von Koch.

nhập mô tả hình ảnh ở đây

Dưới đây là một số đại diện ascii của các lần lặp khác nhau:

n=1
__
\/

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

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

Vì rõ ràng có giới hạn về độ phân giải của đại diện ascii, chúng ta phải phóng to kích thước của bông tuyết theo hệ số 3 cho mỗi lần lặp để hiển thị thêm chi tiết.

Viết mã ngắn nhất để xuất ra bông tuyết theo cùng một kiểu cho n = 4

Chương trình của bạn không nên có bất kỳ đầu vào.
Chương trình của bạn nên viết bông tuyết vào bàn điều khiển.


Bông tuyết tuyết .. một thẻ .. thật thú vị .. !! .. có vẻ như bạn sẽ bắn thêm nhiều câu hỏi vào thẻ này :)
Aman ZeeK Verma

5
Quá ngắn cho một câu trả lời: wolframalpha.com/input/?i=koch+snowflower+4 : D
Tiến sĩ belisarius

1
Có nên thay đổi câu trả lời được chấp nhận? Có những giải pháp ngắn hơn bây giờ.
Timwi

Câu trả lời:


2

Python, 338 byte

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

Chỉ là một khai thác unicode

chạy ở ideone


5
Đủ công bằng, nhưng chắc chắn điều đó sẽ làm cho tệp nguồn dài hơn 300 byte.
Timwi

liên kết bị hỏng
Chiel ten Brinke

10

Python, 650 612 594 574 ký tự

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

Điều này hoạt động bằng cách mở rộng tam giác theo hệ số 3 mỗi lần. Để làm điều đó, chúng ta cần theo dõi xem mỗi biểu tượng là một ranh giới bên trái hay bên phải (ví dụ: cách /mở rộng phụ thuộc vào phía bên nào /là bên trong). Chúng tôi sử dụng các ký hiệu khác nhau cho hai trường hợp có thể, như sau:

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

Các dbiến xử lý các trường hợp đặc biệt, nếu việc mở rộng một anhu cầu để mở rộng vào 3x3 ở hàng tiếp theo.


+1 để nhận câu trả lời đầu tiên trên bảng. Tôi nghĩ bạn có thể thay thế khoảng trắng kép bằng một tab trong vòng lặp for. Ngoài ra, hãy thử sử dụng if k <"C" thay vì K == "A", v.v ... Bây giờ tôi sẽ phải xem xét kỹ hơn thuật toán của bạn :)
gnibbler 17/211

Bạn có thể loại bỏ nhiều câu lệnh if với một mảng kết hợp không? Và có thể các câu lệnh thay thế chuỗi có thể được rút ngắn bằng một mảng.
Nabb

('acEei',r'_/\\ ')=> ('aecEi','_\/\ ')tiết kiệm thêm 1. Bạn cũng có thể muốn kiểm tra unicode.translate().
gnibbler

Điều này cũng in khoảng 18 dòng mới trước bông tuyết, nhưng tôi cho rằng OP không chỉ định liệu có gì khác ngoài bông tuyết có thể được in hay không.
RomanSt

6

Mã máy 16 bit MS-DOS: 199 byte

Giải mã bằng cách sử dụng trang web này , lưu dưới dạng tệp 'koch.com' và thực hiện từ dấu nhắc lệnh 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==

Cập nhật

Đây là phiên bản trình biên dịch dễ đọc:

  ; 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

Hủy bỏ ma thuật :), xin vui lòng giúp tôi hiểu điều này (ít nhất cung cấp một liên kết về những gì bạn đã làm)
Aman ZeeK Verma

@Aman: Nó sử dụng mô tả hệ thống L của đường cong Koch để vẽ đầu ra. Mức độ chi tiết được đặt trong thanh ghi SI mặc dù kích thước được giới hạn ở mức 252 ký tự trên mỗi dòng. Bạn sẽ cần sửa đổi mã in để có các dòng dài hơn 79 ký tự (nghĩa là thay đổi nơi ghi các ký tự '\ n $').
Skizz

cũng có thể sử dụng "scAA...w==".decode("base64")để giải mã trong Python2 (không hoạt động với Python3)
gnibbler

+1 bây giờ tôi có một máy windows để chạy nó. Bất kỳ cơ hội bạn có thể bao gồm phiên bản asm?
gnibbler

2
@mellamokb: err, vì tất cả các mã nguồn có sẵn?
Skizz

4

Perl, 176 175 byte

Đăng bài này như một câu trả lời riêng vì nó sử dụng tệp nguồn nhị phân, có lẽ hơi gian lận. Nhưng xem xét rằng đó vẫn là mã nguồn Perl , tôi nghĩ thật đáng chú ý khi nó đánh bại giải pháp mã máy MS-DOS !

Nguồn dưới dạng mã hóa base64

JF89IsLApwag0dhnMmAmMEcGIAcGQNHYwsDRFLsQ0djCwKcGoNHYwsDRFDdbECYwcRUxe1DCwNEUuxDR2
CI7c14uXiR4PW9yZCQmOyQieCgkeD4+MykucXcoXCAvXyBfXy8gXC8gX18gX1wgLyBfXy9cX18pWyR4Jj
ddXmVnO3NeLnsyN31eJF89cmV2ZXJzZSQmO3l+L1xcflxcL347cHJpbnQkJi4kXy4kL15lZw==

Một chút dễ đọc hơn

Thay thế tất cả các trường hợp /<[0-9a-f]+>/bằng dữ liệu nhị phân có liên quan:

# 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

Trong phiên bản này, bông tuyết được mã hóa theo cách sau:

  • 8 bit trong mỗi byte được chia như thế này:

    +---+---+---+---+---+---+---+---+
    |      5 bits       |   3 bits  |
    +---+---+---+---+---+---+---+---+
              R               C
    
  • Rmã hóa một loạt các không gian. Lần chạy dài nhất là 27 ký tự, vì vậy tất cả các lần chạy phù hợp với 5 bit.

  • Cmã hóa một chuỗi các ký tự được tìm kiếm đơn giản trong mảng chữ. (Tôi đã từng có các bảng mã hơi điên hơn ở đây, nơi chỉ chứa mảng / \ _, nhưng mã Perl cần thiết để giải mã nó dài hơn ...)

  • Tôi may mắn rằng dữ liệu nhị phân không chứa bất kỳ "/ 'hoặc \sẽ cần thoát. Tôi không có kế hoạch này. Nhưng ngay cả khi nó đã làm, tôi có thể chỉ cần thay đổi thứ tự của các mục trong mảng để sửa nó.

  • Thật đáng ngạc nhiên khi giải pháp đơn giản này được so sánh với hàng chục giải pháp khác mà tôi đã trải qua trước khi tôi đưa ra giải pháp này. Tôi đã thử nghiệm với nhiều mã hóa bitwise khác nhau phức tạp hơn mã hóa này và tôi chưa bao giờ nghĩ rằng một mã đơn giản hơn có thể đáng giá chỉ đơn giản vì mã Perl để giải mã nó sẽ ngắn hơn. Tôi cũng đã cố gắng nén các lần lặp lại trong dữ liệu bằng cách sử dụng phép nội suy biến đổi (xem câu trả lời khác), nhưng với phiên bản mới nhất không thu được bất kỳ ký tự nào nữa.


3

Con trăn, 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('/')])

Với một khoảng trắng nhiều hơn:

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

Phía bên trái được nén; phía bên phải được sao chép từ phía bên trái.


3

Perl, 224 223 ký tự

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

Một chút dễ đọc hơn

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

Làm thế nào nó hoạt động

Để biết giải thích về cách thức hoạt động của nó, hãy xem câu trả lời khác trong đó tôi đăng tương tự ở dạng nhị phân . Tôi thực sự xin lỗi vì tôi không thực sự tạo ra bông tuyết Koch, chỉ nén nó ...

Những phiên bản trước

  • (359) Mã hóa toàn bộ bông tuyết thay vì chỉ nửa bên trái. Không gian được bao gồm trong mã hóa bit; không có chiều dài nào Đã sử dụng một số biến nội suy cộng với một @_mảng được truy cập bằng cách sử dụng s/\d/$_[$&]/eg. Dòng mới được mã hóa thành !.

  • (289) Phiên bản đầu tiên chỉ mã hóa nửa trái của bông tuyết.

  • (267) Phiên bản đầu tiên sử dụng mã hóa độ dài chạy cho khoảng trắng.

  • (266) Thay đổi ' 'thành $".

  • (224) Nén hoàn toàn khác nhau, được mã hóa thành cơ sở 64. (Bây giờ tương đương với phiên bản nhị phân .)

  • (223) Nhận ra rằng tôi có thể đặt bản in bên trong trạm biến áp cuối cùng và do đó lưu dấu chấm phẩy.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.