Graficzne przedstawienie Koch Snowflake

13

Wygeneruj płatek śniegu Koch

Płatek śniegu Koch to trójkąt, który dla każdego ndodaje kolejny punkt równoboczny na środku każdej strony: http://en.wikipedia.org/wiki/Koch_snowflake#Properties

Mieliśmy już Koch Snowflake dla n=4 . Nowym wyzwaniem jest narysowanie płatka śniegu Koch z dowolnym nmiędzy 1i 10.

Zasady

Płatki śniegu nie mogą być zakodowane na stałe w programie ani w plikach - muszą zostać wygenerowane przez Twój program.

Twój program musi obsługiwać wszystkie rozmiary nod 1 do 10.

Liczba stron musi zostać wprowadzona przez użytkownika za pomocą standardowego wejścia.

Musisz wydrukować graficzną reprezentację płatka śniegu na ekranie.

Próbkuj płatki śniegu Koch o wartościach nrównych 1, 2, 3 i 4 (zielone linie tylko dla przejrzystości, nie odtwarzaj ich):

Koch Płatki śniegu

W przypadku remisu wygrywa program z największą liczbą głosów pozytywnych (konkurs pop).

Społeczność
źródło
Nie rozumiem tego: „Musisz użyć funkcji, aby obliczyć, gdzie umieścić piksel. Jeśli twój program nie ma wbudowanej funkcji do tego celu, możesz odliczyć koszt wdrożenia jednej z twojego wyniku. „ Jaki piksel
xnor
@xnor Pierwotnie miało to na celu obliczenie, jak narysować płatek śniegu na podstawie liczby pikseli / znaków (wyzwanie było pierwotnie również wyzwaniem artystycznym ASCII). Większość ludzi prawdopodobnie po prostu użyje linii, więc to usunę.
Czy można narysować wypełniony cały płatek śniegu?
xnor
Oczywiście. Ten komentarz musi być dłuższy.
Poza n=7tym na ekranie komputera nie widać nowo dodanych trójkątów w płatku śniegu. Czy jest jakikolwiek „najlepszy wysiłek”? Czy istnieje minimalna rozdzielczość dla rozwiązań opartych na pikselach?
xnor

Odpowiedzi:

7

Mathematica 72

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

n = 3

wprowadź opis zdjęcia tutaj

Dzięki za alephalpha.

chyanog
źródło
Dobra robota. Zagraj w golfa dwoma postaciami, a wygrasz!
@ Hosch250 Zaktualizowano, dziękuję.
chyanog
Możesz używać AnglePathw Mathematica 10.1.
alephalpha
@chyaongGraphics@Line@AnglePath[Nest[Join@@({-1,2,-1,#}&/@#)&,{2,2,2},Input[]-1]Pi/3]
alephalpha
1
@alephalpha 73 chars:ListLinePlot@AnglePath[Nest[Join@@({#,1,4,1}&/@#)&,{4,4,4},Input[]-1]π/3]
chyanog
15

MATLAB, 119 115

W nietypowym cyklu wydarzeń odkryłem, że ten program faktycznie działał lepiej, gdy grałem w golfa. Po pierwsze, stało się znacznie szybsze z powodu wektoryzacji. Teraz wyświetla pomocne podpowiedź ~n:~przypominające użytkownikowi, którą ilość wprowadzić!

Newlines nie są częścią programu.

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

ojest dowolnym ciągiem równym modułowi[0 2 4 0] 6. e iπ / 3 podniesione do tych mocy daje wierzchołki równobocznego trójkąta w płaszczyźnie zespolonej. Pierwszy kronsłuży do wykonania kopii listy punktów, z których każdy jest powielany 4 razy. ~~oto wygodny sposób na uzyskanie wektora 4. Po drugie diff(P)znajduje wektor między każdą parą kolejnych punktów. Wielokrotności tego wektora (0, 1/3, (1 + e -iπ / 3 ) / 3 i 2/3) są dodawane do każdego ze starych punktów.

feersum
źródło
Uhm, czy mógłbyś wyjaśnić nieco więcej, jak działa ten kod? Myślałem, że znam Matlaba, ale to jest ... szaleństwo? =)
błąd
@flawr Dodałem kilka notatek, czy to pomaga?
feersum
Dziękuję Ci bardzo! Będę miał na uwadze tę sztuczkę polegającą na nadużywaniu sznurków =)
wada
9

T-SQL: 686 (bez formatowania)

Dla SQL Server 2012+.

Mimo że nigdy nie będzie to rywal, musiałem sprawdzić, czy uda mi się to zrobić w języku T-SQL. Zniknęło podejście polegające na rozpoczęciu od trzech początkowych krawędzi, a następnie ponownym przejściu przez każdą krawędź i zastąpieniu ich 4 krawędziami na każdym poziomie. Wreszcie połączenie wszystkiego w jedną geometrię dla poziomu określonego dla @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

wprowadź opis zdjęcia tutaj wprowadź opis zdjęcia tutaj

MickyT
źródło
Nie miałem pojęcia, że ​​takie czarodziejstwo można osiągnąć dzięki 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

Definiuje funkcję kz parametrem jednopoziomowym.

Edytować

W tym internetowym edytorze http://www.calormen.com/jslogo/ możesz dodać, k readwordaby użyć monitu o wprowadzenie danych, ale z jakiegoś powodu to polecenie nie obsługuje standardowego skrótu rw.

Poniższe rozwiązanie 102 znaków działa w USBLogo ze standardowym wejściem, jak określono w pytaniu. Jednak kod wymagał drobnych zmian, ponieważ UCBLogo ma dziwny parser. Wymaga toi endmusi znajdować się w osobnych wierszach, a przestrzeń :jest wymagana, ale z drugiej strony :są opcjonalne.

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
źródło
Jak prowadzisz LOGO?
Beta Decay
@BetaDecay Użyłem tego: logo.twentygototen.org, ale to był pierwszy znaleziony przez mnie: calormen.com/jslogo Możesz także zainstalować 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

Jak poprzednio, ale w czerni i bieli, w wersji bez golfa (ale usprawnione) i golfa. Nie jest zwycięzcą, mimo że robi to w ten sposób, unikając potrzeby specjalnego leczenia dla 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

wprowadź opis zdjęcia tutaj

REV 0

Zgodnie z odpowiedzią PO na @xnor, wypełnione płatki śniegu są OK. Ta odpowiedź została zainspirowana komentarzem xnora. Kolory są po prostu dla zabawy i pokazują, jak jest zbudowany. Weź trójkąt (w tym przypadku magenta) i nałóż na siebie 6 trójkątów 1/3 podstawy.

  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

wprowadź opis zdjęcia tutaj

Level River St
źródło
1
Podoba mi się to, jak 7 z nich połączyło się.
@ hosch250 Rzeczywiście, wydaje mi się, że „wynalazłem” nowy fraktal, którego sylwetka okazuje się płatkiem śniegu Koch, a jeśli usuniesz część karmazynową, pozostanie ci 6 mniejszych płatków śniegu Koch. Wersja w golfa będzie tylko zwykłą czarną sylwetką, ale pozostawiam ten obraz również.
Level River St
Czy piszesz to BBC Basic czy BBC BASIC? Ja wybieram to drugie, ale nie wiem, czy to jest poprawne ...
Rozpad
2
@BetaDecay BASIC to skrót dla uniwersalnego standardowego / symbolicznego kodu instrukcji dla początkujących. Bit „Standardowy” jest dyskusyjny, ponieważ istnieje wiele wariantów. en.wikipedia.org/wiki/BASIC . Większość wariantów BASIC preferuje wersję pisaną wielkimi literami, ale zgodnie ze stroną Wikipedii Visual Basic preferuje małe litery. Wydaje mi się, że BBC BASIC w wersji wysyłanej był wielką literą. Korzystam z wersji na bbcbasic.co.uk/bbcwin/bbcwin.html . Jest wielka na stronie i IDE, więc powiedziałbym, że wielka wersja jest bardziej poprawna. Ale nie sądzę, żeby to miało znaczenie.
Level River St
Ach, w porządku, będę kontynuował pisanie wielkimi literami
Rozpad Beta
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[]]

wprowadź opis zdjęcia tutaj

Klip bonusowy zmieniający kąt środkowego elementu

wprowadź opis zdjęcia tutaj

śmigać
źródło
6

Python 3 - 139

Korzysta z biblioteki grafiki żółwia.

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))])
Rozpad beta
źródło
Chłodny. Podoba mi się twoje oparte na ciągach podejście do znajdowania kształtu z nie więcej niż dwoma wierszami kodu! Ale nie można sprawdzić "G">j, "Q"<ji użyć fd(9/b), aby zapisać 3 bajty? Ponadto można uniknąć ifmnożenia instrukcji, np ("G">j). Argumentu 9/bi umieścić je wszystkie w jednym wierszu for. O! Następnie możesz nawet łączyć rti ltużywać120*(...)-60*(...)
Falko
To wydaje się renderować wejście płatka śniegu Koch + 1. Wejście 1 powinno być po prostu trójkątem, jak pokazano na powyższym obrazku.
@ Falko Dzięki za całą tę pomoc!
Beta Decay
@ hosch250 Edytowane
Beta Decay
Teraz nic nie rysuje, a wejście 1 tworzy błąd dzielenia przez 0.
4

Python 3, 117 bajtów

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)

Metoda:

  • Rozwiązanie wykorzystuje grafikę żółwia Pythona.
  • n jest input - 1
  • Zaczynając od łańcucha 0000, łączymy każdą jego postać 101 niteracyjnie z eval trick (dzięki za to @xnor).
  • Dla każdego znaku w ostatnim ciągu skręcamy o 60 stopni w prawo lub 120 stopni w lewo w zależności od wartości znaku ( 1lub 0), a następnie przesuwamy do przodu o długość ( 99/3^n), która gwarantuje podobny rozmiar dla wszystkich n.
  • Ostatni 0ciąg będzie bezużyteczny, ale przerysowuje tę samą linię, co pierwsze 0losowanie.

Przykładowe dane wyjściowe dla input = 3:

koch

randomra
źródło
2

R: 240 175

Ponieważ próbuję ominąć R, oto inna wersja. Prawdopodobnie istnieją o wiele lepsze sposoby na to i cieszę się, że otrzymuję wskazówki. To, co zrobiłem, wydaje się bardzo skomplikowane.

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

wprowadź opis zdjęcia tutaj

MickyT
źródło
2

Wise fwom youw gwave ...

Wiedziałem, że chcę spróbować zaimplementować to w Befunge-98 za pomocą TURT, ale nie mogłem wymyślić, jak to zrobić i siedziałem na nim przez kilka miesięcy. Teraz dopiero niedawno wymyśliłem sposób na zrobienie tego bez konieczności samodzielnej modyfikacji! A więc...

Befunge-98 z odciskiem palca 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

Najpierw zdobądźmy trochę szczegółów implementacji:

  • Przetestowałem to za pomocą CCBI 2.1 , którego implementacja TURT (odcisk palca grafiki żółwia) powoduje I„wydruk” obrazu do pliku SVG. Jeśli uruchomisz to w CCBI bez argumentu polecenia --turt-line=PATH, domyślnie wyjdzie jako plik o nazwie CCBI_TURT.svg. To jest najbliższe, jakie mogłem przyjść, aby „wydrukować graficzną reprezentację płatka śniegu na ekranie” z dostępnymi tłumaczami Funge, jakie mogłem znaleźć. Może kiedyś będzie lepszy tłumacz, który ma wyświetlacz graficzny dla żółwia, ale na razie ...
  • Na końcu musi być nowy wiersz, aby CCBI mógł go uruchomić bez zawieszenia (jest to uwzględnione w liczbie znaków). Wiem, prawda?

Zasadniczo działa to przy użyciu stosu jako rodzaju prowizorycznego systemu L i rozszerzaniu go w locie. Przy każdym podaniu, jeśli najwyższy numer na stosie to:

  • -2, a następnie drukuje i zatrzymuje się;
  • -1, żółw obraca się o 60 stopni w lewo;
  • 0, obraca się o 120 stopni w prawo;
  • 1, przesuwa się do przodu (tutaj o 15 pikseli, ale można to zmienić, modyfikując fw ostatniej linii);
  • jakaś liczba n, która wynosi 2 lub więcej, następnie jest rozszerzana na stosie do n-1, -1, n-1, 0, n-1, -1, n-1.

Ponieważ n = 10proces ten trwa bardzo długo (kilka minut w moim systemie), a wynikowy plik SVG ma rozmiar ~ 10 MB i jest niewidoczny podczas przeglądania w przeglądarce, ponieważ nie można dopasować rozmiaru pędzla za pomocą TURT. IrfanView wydaje się działać przyzwoicie, jeśli masz odpowiednie wtyczki. Nie jestem zbyt obeznany z SVG, więc nie wiem, jaka jest preferowana metoda przeglądania tych plików (szczególnie, gdy są naprawdę duże).

Hej, przynajmniej działa - co, biorąc pod uwagę, że jest Befunge, jest czymś, za co można być wdzięcznym.

Kasran
źródło
1

Python 2, 127 bajtów

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)
dieter
źródło
1
Graty za 50 000. post tutaj.
Andrew