Koch kar tanesi - codegolf


21

Koch kar tanesi (aynı zamanda Koch yıldız Koch ada olarak da bilinir) bir matematiksel eğrisi ve erken fraktal eğrilerinin tarif edilmiştir etmektir. "Temel geometriden inşa edilen teğetsiz sürekli bir eğri üzerinde" başlıklı 1904 tarihli bir makalede yer alan Koch eğrisine dayanmaktadır (orijinal Fransızca başlık: "Sur une courbe sans tangente sanse İsveçli matematikçi Helge von Koch.

görüntü tanımını buraya girin

İşte çeşitli yinelemelerin ascii temsilleri:

n=1
__
\/

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

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

Açıkça, ascii temsilinin çözünürlüğünde bir sınır olduğu için, her bir yinelemenin ekstra ayrıntı göstermesi için kar tanesinin boyutunu 3 kat büyütmeliyiz.

Kar tanesini n = 4 için aynı stille çıkarmak için en kısa kodu yazın

Programınız herhangi bir giriş yapmamalıdır.
Programınız kar tanesini konsola yazmalıdır.


Koch-snowflake .. a tag .. thats interesting .. !! .. bu etiket üzerine daha fazla soru sormaya başlamış gibi görünüyor :)
Aman ZeeK Verma


1
Kabul edilen cevap değiştirilmeli mi? Şimdi daha kısa çözümler var.
Timwi

Yanıtlar:


2

Python, 338 bayt

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

Bir başka unicode istismarı

ideone'da koşmak


5
Yeterince adil, ancak bu kesinlikle kaynak dosyayı 300 bayttan daha uzun yapar.
Timwi

bağlantı koptu
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})

Bu, üçgeni her seferinde 3 kat artırarak çalışır. Bunu yapmak için, her sembolün sol ya da sağ bir sınır olup olmadığını takip etmemiz gerekir (örneğin, nasıl /genişletileceği /iç tarafın hangi tarafına bağlıdır ). İki olası durum için farklı semboller kullanıyoruz:

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

dDeğişken bir genişleme özel durumda işler aihtiyaçları sonraki satırda 3x3 içine uzatmak.


Tahtada ilk cevabı almak için +1. Sanırım çift boşlukları for döngüsündeki bir sekmeyle değiştirebilirsiniz. Ayrıca, eğer K == "A" vs. yerine k <"C" yi kullanmayı deneyin. Şimdi algoritmanıza daha yakından
bakmam gerekecek

Bir çok if ifadesini bir ilişkisel dizi ile kaldıramaz mısınız? Ve belki de zincirli değiştirme ifadeleri bir dizi ile kısaltılabilir.
Nabb

('acEei',r'_/\\ ')=> ('aecEi','_\/\ ')1 tane daha kaydeder. Ayrıca kontrol etmek isteyebilirsiniz unicode.translate().
gnibbler

Bu aynı zamanda kar tanesinden önce yaklaşık 18 yeni satır basar, ancak OP'nin kar tanesinden başka bir şeyin yazdırılıp yazdırılamayacağını belirtmediğini farz ediyorum .
RomanSt

6

MS-DOS 16 bit makine kodu: 199 bayt

Bu siteyi kullanarak şifresini çözün, 'koch.com' dosyası olarak kaydedin ve WinXP komut isteminden çalıştırın.

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

Güncelleştirme

İşte okunması kolay bir montajcı sürümü:

  ; 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

Mutlak sihir :), lütfen bunu anlamama yardım et (en azından, yaptıklarınla ​​ilgili bir bağlantı
sağla

@Aman: Çıktıyı çizmek için Koch eğrisinin L sistemi açıklamasını kullanır. Ayrıntı seviyesi SI kayıt defterinde ayarlanır, ancak boyut satır başına 252 karakterle sınırlıdır. 79 karakterden daha uzun satırlar almak için yazdırma kodunu değiştirmeniz gerekir (örneğin, '\ n $' karakterlerini yazdığı yeri değiştirin).
Skizz

"scAA...w==".decode("base64")Python2 de kodunu çözmek için de kullanabilirsiniz (Python3 için işe yaramaz)
gnibbler

+1 şimdi çalıştıracak bir pencere makinem var. ASM versiyonunu ekleyebilme şansın var mı?
gnibbler

2
@ mellamokb: err, çünkü tüm kaynak kodları mevcut olabilir?
Skizz

4

Perl, 176 175 bayt

Bunu ayrı bir cevap olarak yayınlamak, muhtemelen biraz hileli olan bir ikili kaynak dosya kullandığından. Ancak yine de Perl kaynak kodu olduğu düşünüldüğünde, MS-DOS makine kodu çözümünü yenmesi dikkat çekicidir !

Base64 olarak kodlanmış kaynak

JF89IsLApwag0dhnMmAmMEcGIAcGQNHYwsDRFLsQ0djCwKcGoNHYwsDRFDdbECYwcRUxe1DCwNEUuxDR2
CI7c14uXiR4PW9yZCQmOyQieCgkeD4+MykucXcoXCAvXyBfXy8gXC8gX18gX1wgLyBfXy9cX18pWyR4Jj
ddXmVnO3NeLnsyN31eJF89cmV2ZXJzZSQmO3l+L1xcflxcL347cHJpbnQkJi4kXy4kL15lZw==

Biraz daha okunabilir

Tüm örneklerini /<[0-9a-f]+>/ilgili ikili verilerle değiştirin:

# 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

Bu versiyonda, kar tanesi aşağıdaki şekilde kodlanmıştır:

  • Her bayttaki 8 bit şöyle bölünür:

    +---+---+---+---+---+---+---+---+
    |      5 bits       |   3 bits  |
    +---+---+---+---+---+---+---+---+
              R               C
    
  • Rbir boşluk akışını kodlar. En uzun çalıştırma 27 karakterdir, bu nedenle tüm çalıştırmalar 5 bite uyar.

  • Cdeğişmez dizide basitçe görünen karakter dizisini kodlar. (Burada sadece dizinin bulunduğu yerlerde biraz daha çılgın kodlamalar vardı / \ _, ama kodunu çözmek için gerekli olan Perl kodu daha uzundu ...)

  • İkili verinin kaçması gereken herhangi bir "/ 'veya içermediği için şanslıyım \. Bunun için planlamadım. Ama yapmış olsa bile, muhtemelen onu düzeltmek için dizideki öğelerin sırasını değiştirebilirdim.

  • Bu çözüm bu kadar gelmeden önce gittiğim diğer çözümlerin onlarca ile karşılaştırıldığında ne kadar basit olduğunu şaşırtıcı. Bundan daha karmaşık birçok farklı bitsel kodlama ile denemeler yaptım ve basit bir kodun buna değebileceği hiç aklıma gelmedi, çünkü kod çözülecek Perl kodu daha kısa olacaktı. Ayrıca değişken enterpolasyonu kullanarak verideki tekrarları sıkıştırmaya çalıştım (diğer cevaba bakınız), ancak artık karakter kazanmayan en yeni sürümle.


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

Biraz daha fazla boşlukla:

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

Sol taraf sıkıştırılmıştır; sağ taraf sol taraftan üretilir.


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

Biraz daha okunabilir

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

Nasıl çalışır

Nasıl çalıştığının bir açıklaması için, aynı şeyi ikilik olarak gönderdiğim diğer cevaba bakınız . Gerçekten Koch kar tanesini oluşturmadığım için üzgünüm , sadece sıkıştırıyorum ...

Önceki sürümler

  • (359) Sadece sol yarının yerine tüm kar tanesini kodladı. Bit kodlamasına boşluklar dahil edildi; Henüz koşu uzunluğu yok. Birkaç enterpolasyonlu değişken, ayrıca @_kullanılarak erişilen bir dizi kullanılır s/\d/$_[$&]/eg. Newlines olarak kodlandı !.

  • (289) Kar tanesinin yalnızca sol yarısını kodlayan ilk versiyon.

  • (267) Boşluklarda kodlama kullanan ilk sürüm.

  • (266) Değişim ' 'için $".

  • (224) Temel-64 olarak kodlanan kökten farklı sıkıştırma. (Şimdi ikili sürüme eşdeğer .)

  • (223) Baskıyı son alt maddeye koyabileceğimi ve böylece bir noktalı virgül kaydedebileceğimi fark ettim.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.