Koch Snowflake - codegolf


21

Il fiocco di neve di Koch (noto anche come la stella di Koch e l'isola di Koch) è una curva matematica e una delle prime curve frattali che sono state descritte. Si basa sulla curva di Koch, che apparve in un documento del 1904 intitolato "Su una curva continua senza tangenti, costruibile dalla geometria elementare" (titolo originale francese: "Sur une courbe continue sans tangente, obtenue par une construction géométrique élémentaire") di il matematico svedese Helge von Koch.

inserisci qui la descrizione dell'immagine

Ecco alcune rappresentazioni ascii di varie iterazioni:

n=1
__
\/

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

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

Poiché esiste ovviamente un limite alla risoluzione della rappresentazione ASCII, dobbiamo ingrandire la dimensione del fiocco di neve di un fattore 3 per ogni iterazione per mostrare il dettaglio in più.

Scrivi il codice più breve per generare il fiocco di neve nello stesso stile per n = 4

Il tuo programma non dovrebbe ricevere alcun input.
Il tuo programma dovrebbe scrivere il fiocco di neve sulla console.


Koch-snowflake ..un tag .. questo è interessante .. !! .. sembra che farai più domande su questo tag :)
Aman ZeeK Verma

5
Troppo breve per una risposta: wolframalpha.com/input/?i=koch+snowflake+4 : D
Dr. belisarius,

1
La risposta accettata deve essere modificata? Ci sono soluzioni più brevi ora.
Timwi,

Risposte:


2

Python, 338 byte

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

Solo un altro exploit Unicode

correre a ideone


5
Abbastanza giusto, ma sicuramente ciò renderebbe il file di origine più lungo di 300 byte.
Timwi,

il collegamento è interrotto
Chiel ten Brinke il

10

Python, 650 612 594 574 caratteri

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

Questo funziona espandendo il triangolo di un fattore 3 ogni volta. Per fare ciò, dobbiamo tenere traccia del fatto che ogni simbolo sia un limite sinistro o destro (ad es. Come /viene espanso dipende da quale lato /è l'interno). Usiamo simboli diversi per i due casi possibili, come segue:

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

La dvariabile gestisce il caso speciale in cui l'espansione di un adeve estendersi nel 3x3 nella riga successiva.


+1 per ottenere la prima risposta alla lavagna. Penso che puoi sostituire i doppi spazi con una scheda nel ciclo for. Prova anche a usare se k <"C" invece di K == "A" ecc. Ora dovrò guardare più da vicino il tuo algoritmo :)
gnibbler,

Non riesci a rimuovere le molte istruzioni if ​​con un array associativo? E forse le istruzioni di sostituzione concatenate possono essere abbreviate con un array.
Nabb,

('acEei',r'_/\\ ')=> ('aecEi','_\/\ ')salva 1 altro. Potresti anche voler controllare il unicode.translate().
Gnibbler,

Questo stampa anche circa 18 nuove righe prima del fiocco di neve, ma suppongo che l'OP non abbia specificato se si può stampare qualcosa di diverso dal fiocco di neve.
Roman,

6

Codice macchina 16 bit MS-DOS: 199 byte

Decodifica utilizzando questo sito , salva come file 'koch.com' ed esegui dal prompt dei comandi di 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==

Aggiornare

Ecco una versione assembler di facile lettura:

  ; 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

Abolire la magia :), ti prego, aiutami a capire questo (almeno fornisci un link su quello che hai fatto)
Aman ZeeK Verma,

@Aman: usa una descrizione del sistema L della curva di Koch per disegnare l'output. Il livello di dettaglio è impostato nel registro SI sebbene la dimensione sia limitata a 252 caratteri per riga. Dovrai modificare il codice di stampa per ottenere righe più lunghe di 79 caratteri (ovvero cambia dove scrive i caratteri '\ n $').
Skizz,

può anche usare "scAA...w==".decode("base64")per decodificare in Python2 (non funziona per Python3)
gnibbler,

+1 ora che ho un computer Windows su cui eseguirlo. Qualche possibilità che puoi includere nella versione asm?
Gnibbler,

2
@mellamokb: err, perché forse tutto il codice sorgente è disponibile?
Skizz,

4

Perl, 176 175 byte

Pubblicando questo come una risposta separata perché usa un file sorgente binario, che è forse un po 'economico. Ma considerando che è ancora il codice sorgente Perl , penso sia straordinario che batte la soluzione di codice macchina MS-DOS !

Sorgente con codifica base64

JF89IsLApwag0dhnMmAmMEcGIAcGQNHYwsDRFLsQ0djCwKcGoNHYwsDRFDdbECYwcRUxe1DCwNEUuxDR2
CI7c14uXiR4PW9yZCQmOyQieCgkeD4+MykucXcoXCAvXyBfXy8gXC8gX18gX1wgLyBfXy9cX18pWyR4Jj
ddXmVnO3NeLnsyN31eJF89cmV2ZXJzZSQmO3l+L1xcflxcL347cHJpbnQkJi4kXy4kL15lZw==

Un po 'più leggibile

Sostituisci tutte le istanze di /<[0-9a-f]+>/con i dati binari rilevanti:

# 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 questa versione, il fiocco di neve è codificato nel modo seguente:

  • Gli 8 bit in ogni byte sono divisi in questo modo:

    +---+---+---+---+---+---+---+---+
    |      5 bits       |   3 bits  |
    +---+---+---+---+---+---+---+---+
              R               C
    
  • Rcodifica una serie di spazi. La corsa più lunga è di 27 caratteri, quindi tutte le corse si adattano a 5 bit.

  • Ccodifica una sequenza di caratteri che vengono semplicemente cercati nella matrice letterale. (Avevo codifiche leggermente più folli qui dove l'array conteneva solo / \ _, ma il codice Perl necessario per decodificarlo era più lungo ...)

  • Ho la fortuna che i dati binari non contiene alcun "/ 'o \che avrebbero bisogno di fuggire. Non avevo programmato questo. Ma anche se lo avesse fatto, probabilmente avrei potuto semplicemente cambiare l'ordine degli elementi nell'array per risolverlo.

  • È incredibile quanto sia semplice questa soluzione rispetto alle decine di altre soluzioni che ho affrontato prima di inventarlo. Ho sperimentato molte codifiche bit per bit più complesse di questa, e non mi è mai venuto in mente che ne valesse la pena semplicemente una più semplice perché il codice Perl per decodificarlo sarebbe più breve. Ho anche provato a comprimere le ripetizioni nei dati usando l'interpolazione variabile (vedi l'altra risposta), ma con la versione più recente che non guadagna più caratteri.


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

Con un po 'più di spazio bianco:

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

Il lato sinistro è compresso; il lato destro è riprodotto dal lato sinistro.


3

Perl, 224 223 caratteri

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

Un po 'più leggibile

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

Come funziona

Per una spiegazione di come funziona, vedi l'altra risposta in cui invio lo stesso in binario . Mi dispiace davvero di non aver effettivamente generato il fiocco di neve Koch, ma solo di comprimerlo ...

Versione precedente

  • (359) Codificato l'intero fiocco di neve anziché solo la metà sinistra. Gli spazi sono stati inclusi nella codifica dei bit; nessuna lunghezza della corsa ancora. Sono state utilizzate diverse variabili interpolate più un @_array a cui è stato effettuato l'accesso s/\d/$_[$&]/eg. Newline sono stati codificati come !.

  • (289) Prima versione che codificava solo la metà sinistra del fiocco di neve.

  • (267) Prima versione che utilizzava la codifica run-length per gli spazi.

  • (266) Cambia ' 'in $".

  • (224) Compressione radicalmente diversa, codificata come base-64. (Ora equivalente alla versione binaria .)

  • (223) Mi sono reso conto che posso inserire la stampa nell'ultima sottostazione e quindi salvare un punto e virgola.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.