Representasi Grafis dari Koch Snowflake

13

Hasilkan Koch Snowflake

Kepingan salju Koch adalah segitiga yang untuk masing-masing n, titik sama sisi lainnya ditambahkan di tengah masing-masing sisi: http://en.wikipedia.org/wiki/Koch_snowflake#Properties

Kami sudah punya Koch Snowflake tantangan untuk n=4. Tantangan baru adalah menggambar kepingan salju Koch dengan nantara 1dan 10.

Aturan

Kepingan salju mungkin tidak di-hardcode dalam program atau file - mereka harus dihasilkan oleh program Anda.

Program Anda harus mendukung semua ukuran nantara 1 dan 10.

Jumlah sisi harus dimasukkan oleh pengguna melalui std-in.

Anda harus mencetak representasi grafis kepingan salju ke layar.

Cicipi Koch Snowflakes dengan jumlah nsama dengan 1, 2, 3, dan 4 (garis hijau untuk kejelasan saja, jangan mereproduksinya):

Kepingan Salju Koch

Dalam hal tie-breaker, program dengan jumlah upvote terbanyak menang (kontes pop).

Komunitas
sumber
Saya tidak memahami ini: "Anda harus menggunakan fungsi untuk menghitung di mana menempatkan piksel. Jika program Anda tidak memiliki fungsi bawaan untuk tujuan ini, Anda dapat mengurangi biaya penerapan satu dari skor Anda. " Pixel apa?
xnor
@xnor Awalnya dimaksudkan untuk menghitung cara menggambar kepingan salju pada basis per-pixel / karakter (tantangan awalnya juga merupakan tantangan ASCII-art). Kebanyakan orang mungkin hanya akan menggunakan garis, jadi saya akan menghapusnya.
Bisakah satu gambar seluruh kepingan salju diisi?
xnor
Tentu saja. Komentar ini perlu lebih lama.
Selain itu n=7, Anda tidak dapat melihat segitiga yang baru ditambahkan di kepingan salju di layar komputer. Apakah "upaya terbaik" di sini baik-baik saja? Apakah ada resolusi minimum untuk solusi berbasis piksel?
xnor

Jawaban:

7

Mathematica 72

Region@Line@AnglePath[Nest[Join@@({#,1,4,1}&/@#)&,{4,4,4},Input[]-1]π/3]

n = 3

masukkan deskripsi gambar di sini

Terima kasih untuk alephalpha.

chyanog
sumber
Pekerjaan yang baik. Golf dengan dua karakter, dan Anda mendapatkan kemenangan!
@ Hosch250 Diperbarui, Terima kasih.
chyanog
Anda dapat menggunakan AnglePathdalam Mathematica 10.1.
alephalpha
@chyaongGraphics@Line@AnglePath[Nest[Join@@({-1,2,-1,#}&/@#)&,{2,2,2},Input[]-1]Pi/3]
alephalpha
1
@alephalpha 73 karakter:ListLinePlot@AnglePath[Nest[Join@@({#,1,4,1}&/@#)&,{4,4,4},Input[]-1]π/3]
chyanog
15

MATLAB, 119 115

Dalam pergantian kejadian yang tidak biasa, saya menemukan bahwa program ini benar-benar bekerja lebih baik ketika saya bermain golf. Pertama, menjadi lebih cepat karena vektorisasi. Sekarang, ini menampilkan prompt yang membantu ~n:~mengingatkan pengguna tentang jumlah yang akan dimasukkan!

Baris baru bukan bagian dari program.

x=exp(i*pi/3);
o='~n:~';
P=x.^o;
for l=2:input(o);
P=[kron(P(1:end-1),~~o)+kron(diff(P)/3,[0 1 1+1/x 2]) 1];
end;
plot(P)

n = 9: n = 9

oadalah string arbitrer yang sama dengan [0 2 4 0]modulo 6. e iπ / 3 dinaikkan ke kekuatan ini memberikan simpul segitiga sama sisi pada bidang kompleks. Yang pertama krondigunakan untuk membuat salinan daftar poin dengan masing-masing digandakan 4 kali. ~~oadalah cara mudah untuk mendapatkan 4 vektor. Kedua, diff(P)temukan vektor di antara setiap pasangan titik berurutan. Kelipatan vektor ini (0, 1/3, (1 + e -iπ / 3 ) / 3, dan 2/3) ditambahkan ke masing-masing poin lama.

feersum
sumber
Uhm, bisakah Anda menjelaskan lebih banyak bagaimana kode ini bekerja? Saya pikir saya tahu beberapa Matlab tapi ini ... kegilaan ?? =)
flawr
@ flawr Saya menambahkan beberapa catatan, apakah itu membantu?
feersum
Terima kasih banyak! Saya akan mengingat trik penyalahgunaan string =)
flawr
9

T-SQL: 686 (tidak termasuk pemformatan)

Untuk SQL Server 2012+.

Meskipun ini tidak akan pernah menjadi pesaing, saya harus melihat apakah saya bisa menyelesaikannya dalam T-SQL. Pergi untuk pendekatan dimulai dengan tiga tepi awal, kemudian berulang melalui setiap tepi dan menggantinya dengan 4 tepi untuk setiap level. Akhirnya penyatuan semuanya menjadi geometri tunggal untuk level yang ditentukan untuk @i

DECLARE @i INT=8,@ FLOAT=0,@l FLOAT=9;
WITH R AS(
    SELECT sX,sY,eX,eY,@l l,B,1i
    FROM(VALUES(@,@,@l,@,0),(@l,@,@l/2,SQRT(@l*@l-(@l/2)*(@l/2)),-120),(@l/2,SQRT(@l*@l-(@l/2)*(@l/2)),@,@,-240))a(sX,sY,eX,eY,B)
    UNION ALL
    SELECT a.sX,a.sY,a.eX,a.eY,l/3,a.B,i+1
    FROM R 
        CROSS APPLY(VALUES(sX,sY,sX+(eX-sX)/3,sY+(eY-sY)/3,sX+((eX-sX)/3)*2,sY+((eY-sY)/3)*2))x(x1,y1,x2,y2,x3,y3)
        CROSS APPLY(VALUES(x2+((l/3)*SIN(RADIANS(B-210.))),y2+((l/3)*COS(RADIANS(B-210.)))))n(x4,y4)
        CROSS APPLY(VALUES(x1,y1,x2,y2,B),
            (x3,y3,eX,eY,B),
            (x2,y2,x4,y4,B+60),
            (x4,y4,x3,y3,B-60)
        )a(sX,sY,eX,eY,B)
WHERE @i>i)
SELECT Geometry::UnionAggregate(Geometry::Parse(CONCAT('LINESTRING(',sX,' ',sY,',',eX,' ',eY,')')))
FROM R 
WHERE i=@i

masukkan deskripsi gambar di sini masukkan deskripsi gambar di sini

MickyT
sumber
Saya tidak tahu sihir seperti itu dapat dicapai dengan T-SQL!
Harry Mustoe-Playfair
9

LOGO: 95

to w:c ifelse:c=1[fd 2 lt 60][w:c-1 w:c-1 lt 180 w:c-1 w:c-1]end
to k:c repeat 3[w:c rt 180]end

Menentukan fungsi kdengan parameter level tunggal.

Edit

Di editor online ini http://www.calormen.com/jslogo/ Anda dapat menambahkan k readworduntuk menggunakan prompt untuk input, tetapi karena alasan tertentu perintah ini tidak mendukung singkatan standar rw.

Solusi 102 karakter di bawah ini berfungsi di USBLogo dengan input standar seperti yang ditentukan dalam pertanyaan. Namun kode ini memerlukan sedikit perubahan karena UCBLogo memiliki beberapa pengurai yang aneh. Ini membutuhkan todan endberada di garis dan ruang terpisah sebelum :diperlukan tetapi di sisi lain :adalah opsional.

to w c
ifelse c=1[fd 2 lt 60][w c-1 w c-1 lt 180 w c-1 w c-1]
end
to k c
repeat 3[w c rt 180]
end
k rw
nutki
sumber
Bagaimana Anda menjalankan LOGO?
Beta Decay
@BetaDecay Saya menggunakan ini: logo.twentygototen.org tapi ini yang pertama saya temukan: calormen.com/jslogo Anda juga dapat menginstal USBLogo
nutki
8

BBC BASIC, 179

REV 1

INPUTn
z=FNt(500,470,0,0,3^n/9)END
DEFFNt(x,y,i,j,a)
LINEx-36*a,y-21*a,x+36*a,y-a*21PLOT85,x,y+a*42IFa FORj=-1TO1FORi=-1TO1z=FNt(x+24*a*i,y+j*14*a*(i*i*3-2),i,j,-j*a/3)NEXTNEXT
=0

Seperti sebelumnya, tetapi dalam versi hitam dan putih, dalam versi ungolfed (tapi ramping) dan golf. Bukan seorang pemenang, terlepas dari kenyataan bahwa melakukannya adalah cara menghindari perlunya treament khusus untuk n = 1.

  INPUTn
        REM call function and throw return value away to z
  z=FNt(500,470,0,0,3^n/9)
  END

        REM x,y=centre of triangle. a=scale.
        REM loop variables i,j are only passed in order to make them local, not global.
  DEFFNt(x,y,i,j,a)

        REM first draw a line at the bottom of the triangle. PLOT85 then draws a filled triangle,
        REM using the specified point (top of the triangle) and the last two points visited (those used to draw the line.)
  LINEx-36*a,y-21*a,x+36*a,y-21*a
  PLOT85,x,y+42*a

        REM if the absolute magnitude of a is sufficient to be truthy, recurse to the next level.
        REM j determines if the triangle will be upright, inverted or (if j=0) infinitely small.
        REM i loops through the three triangles of each orientation, from left to right.
  IFa FORj=-1TO1 FORi=-1TO1:z=FNt(x+24*a*i,y+j*14*a*(i*i*3-2),i,j,-j*a/3):NEXT:NEXT

        REM return 0
  =0

masukkan deskripsi gambar di sini

REV 0

Menurut jawaban OP untuk @xnor, diisi dengan kepingan salju OK. Jawaban ini terinspirasi oleh komentar xnor. Warnanya hanya untuk bersenang-senang dan menunjukkan cara pembuatannya. Ambil sebuah segitiga (magenta dalam kasus ini) dan overplot dengan 6 segitiga 1/3 dari dasarnya.

  INPUTn
  z=FNt(500,470,n,1,0,0)
  END

  DEFFNt(x,y,n,o,i,a)
  a=3^n/22
  GCOLn
  MOVEx-36*a,y-o*21*a
  MOVEx+36*a,y-o*21*a
  PLOT85,x,y+o*42*a
  IFn>1FORi=-1TO1:z=FNt(x+24*a*i,y+14*a*(i*i*3-2),n-1,-1,i,a):z=FNt(x+24*a*i,y-14*a*(i*i*3-2),n-1,1,i,a)NEXT
  =0

masukkan deskripsi gambar di sini

Level River St
sumber
1
Saya suka bagaimana 7 dari mereka bergabung.
@ hosch250 Memang, saya sepertinya telah "menemukan" fraktal baru yang siluetnya adalah kepingan salju Koch, dan jika Anda menghapus bagian magenta, Anda dibiarkan dengan 6 kepingan salju Koch yang lebih kecil. Versi golf akan menjadi siluet hitam polos, tapi saya akan membiarkan gambar ini juga.
Level River St
Apakah Anda menulisnya BBC Basic atau BBC BASIC? Saya memilih yang terakhir tetapi saya tidak tahu apakah itu benar ...
Beta Decay
2
@BetaDecay BASIC adalah backronym untuk Kode Instruksi Serba Guna / Simbolis untuk Semua Tujuan Bit "Standar" masih bisa diperdebatkan karena ada begitu banyak varian. en.wikipedia.org/wiki/BASIC . Sebagian besar varian BASIC lebih suka versi huruf besar, tetapi menurut halaman Wikipedia, Visual Basic lebih suka huruf kecil. Saya pikir BBC BASIC yang dikirimkan adalah huruf besar. Saya menggunakan versi di bbcbasic.co.uk/bbcwin/bbcwin.html . Ini huruf besar di situs web dan IDE, Jadi saya akan mengatakan versi huruf besar lebih benar. Tapi saya pikir itu tidak penting.
Level River St
Ahh oke, saya akan melanjutkan dengan versi huruf besar
Beta Decay
8

Mathematica - 177

r[x_, y_] := Sequence[x, RotationTransform[π/3, x]@y, y]
Graphics@Polygon@Nest[
 ReplaceList[#, {___, x_, y_, ___}  Sequence[x,r[2 x/3 + y/3, 2 y/3 + x/3], y]
  ] &, {{0, 0}, {.5, √3/2}, {1, 0}, {0, 0}}, Input[]]

masukkan deskripsi gambar di sini

Klip bonus memvariasikan sudut bagian tengah

masukkan deskripsi gambar di sini

desir
sumber
6

Python 3 - 139

Menggunakan perpustakaan grafis penyu.

from turtle import*
b=int(input())
a=eval(("FR"*3)+".replace('F','FLFRFLF')"*~-b)
for j in a:fd(9/b*("G">j));rt(60*(2-3*("Q">j))*("K"<j))])
Peluruhan Beta
sumber
Keren. Saya suka pendekatan berbasis string Anda untuk menemukan bentuk dengan tidak lebih dari dua baris kode! Tetapi tidak bisakah Anda memeriksa "G">j, "Q"<jdan menggunakannya fd(9/b)untuk menyimpan 3 byte? Selain itu, Anda dapat menghindari ifpenggandaan pernyataan, misalnya ("G">j)dengan argumen 9/bdan menempatkan semuanya dalam satu baris di belakang for. Oh! Kemudian Anda bahkan dapat menggabungkan rtdan ltmenggunakan120*(...)-60*(...)
Falko
Ini muncul untuk membuat input kepingan salju Koch +1. Input 1 seharusnya hanya berupa segitiga seperti yang ditunjukkan gambar di atas.
@Falko Terima kasih atas semua bantuan itu!
Beta Decay
@ hosch250 Diedit
Beta Decay
Sekarang tidak menggambar apa pun, dan input 1 membuat pembagian dengan 0 kesalahan.
4

Python 3, 117 byte

from turtle import*
ht();n=int(input())-1
for c in eval("'101'.join("*n+"'0'*4"+")"*n):rt(60+180*(c<'1'));fd(99/3**n)

Metode:

  • Solusinya menggunakan grafis kura-kura Python.
  • n adalah input - 1
  • Mulai dari string 0000kita gabungkan setiap karakter dengan 101 nwaktu iteratif dengan trik eval (terima kasih kepada @xnor untuk itu).
  • Untuk setiap karakter dalam string terakhir, kita belok 60 derajat ke kanan atau 120 derajat ke kiri berdasarkan nilai karakter ( 1atau 0) dan kemudian bergerak maju panjang (99/3^n ) yang menjamin ukuran yang sama untuk semua n.
  • Yang terakhir 0dalam string tidak akan berguna tetapi hanya menggambar ulang garis yang sama dengan yang pertama kali 0diundi.

Contoh output untuk input = 3:

koch

randomra
sumber
2

R: 240 175

Karena saya mencoba untuk mendapatkan kepalaku di sekitar R, inilah versi lain. Mungkin ada banyak cara yang lebih baik untuk melakukan ini dan saya senang menerima petunjuk. Apa yang saya lakukan tampaknya sangat berbelit-belit.

n=readline();d=c(0,-120,-240);c=1;while(c<n){c=c+1;e=c();for(i in 1:length(d)){e=c(e,d[i],d[i]+60,d[i]-60,d[i])};d=e};f=pi/180;plot(cumsum(sin(d*f)),cumsum(cos(d*f)),type="l")

masukkan deskripsi gambar di sini

MickyT
sumber
2

Wise fwom youw gwave ...

Saya tahu saya ingin mencoba mengimplementasikan ini di Befunge-98 menggunakan TURT, tapi saya tidak tahu bagaimana cara melakukannya dan saya duduk di sana selama beberapa bulan. Sekarang, hanya baru-baru ini, saya menemukan cara untuk melakukannya tanpa menggunakan modifikasi diri! Dan sebagainya...

Befunge-98 dengan sidik jari TURT, 103

;v;"TRUT"4(02-&:0\:0\1P>:3+:4`!*;
>j$;space makes me cry;^
^>1-:01-\:0\:01-\:0
0>I@
^>6a*L
^>ca*R
^>fF

Mari kita dapatkan detail implementasi terlebih dahulu:

  • Saya mengujinya menggunakan CCBI 2.1 , yang penerapan TURT (sidik jari grafis kura-kura) membuat I"mencetak" gambar ke file SVG. Jika Anda menjalankan ini di CCBI tanpa argumen-perintah --turt-line=PATH, itu akan keluar sebagai file bernama CCBI_TURT.svg secara default. Ini yang paling dekat dengan saya "mencetak representasi grafis kepingan salju ke layar" dengan juru bahasa Funge yang tersedia yang bisa saya temukan. Mungkin suatu hari akan ada penerjemah yang lebih baik di luar sana yang memiliki tampilan grafis untuk kura-kura, tetapi untuk sekarang ...
  • Harus ada baris baru di akhir bagi CCBI untuk menjalankannya tanpa menggantung (ini termasuk dengan jumlah karakter). Saya tau?

Pada dasarnya, ini bekerja dengan menggunakan stack sebagai semacam L-system darurat dan memperluasnya dengan cepat. Pada setiap kartu, jika nomor teratas di tumpukan adalah:

  • -2, lalu mencetak dan berhenti;
  • -1, kura-kura berputar berlawanan arah 60 derajat;
  • 0, ternyata searah jarum jam 120 derajat;
  • 1, bergerak maju (dengan 15 piksel di sini, tetapi Anda dapat mengubahnya dengan memodifikasi f pada baris terakhir);
  • beberapa nomor n itu 2 atau lebih besar, kemudian diperluas pada tumpukan ke n-1, -1, n-1, 0, n-1, -1, n-1.

Sebab n = 10, proses ini membutuhkan waktu yang sangat lama (beberapa menit pada sistem saya), dan SVG yang dihasilkan adalah ~ 10MB dalam ukuran dan tidak terlihat ketika dilihat di browser karena Anda tidak dapat menyesuaikan ukuran sikat menggunakan TURT. IrfanView tampaknya berfungsi dengan baik jika Anda memiliki plugin yang tepat. Saya tidak terlalu terbiasa dengan SVG, jadi saya tidak tahu apa metode yang disukai untuk melihat file-file itu (terutama ketika mereka sangat besar).

Hei, setidaknya itu berfungsi - yang, mengingat itu Befunge, adalah sesuatu yang harus disyukuri sendiri.

Kasran
sumber
1

Python 2, 127 byte

from turtle import *
def L(l,d=input()-1):
 for x in[1,-2,1,0]:[L(l,d-1),rt(60*x)] if d>0 else fd(l)
for i in'lol':lt(120);L(9)
pelaku diet
sumber
1
Terima kasih telah mengirim 50.000 posting di sini.
Andrew