Représentation graphique du flocon de neige de Koch


13

Générer un flocon de neige Koch

Un flocon de neige Koch est un triangle qui, pour chacun n, un autre point équilatéral est ajouté au milieu de chaque côté: http://en.wikipedia.org/wiki/Koch_snowflake#Properties

Nous avions déjà un Koch Snowflake de pour n=4. Le nouveau défi est de dessiner un flocon de neige Koch avec n'importe quel nentre 1et 10.

Règles

Les flocons de neige peuvent ne pas être codés en dur dans le programme ou dans les fichiers - ils doivent être générés par votre programme.

Votre programme doit prendre en charge toutes les tailles ncomprises entre 1 et 10.

Le nombre de côtés doit être entré par l'utilisateur via std-in.

Vous devez imprimer une représentation graphique du flocon de neige à l'écran.

Exemple de flocons de neige Koch avec n1, 2, 3 et 4 égaux (lignes vertes pour plus de clarté, ne les reproduisez pas)

Flocons de neige Koch

En cas de bris d'égalité, le programme avec le plus grand nombre de votes positifs gagne (concours pop).


Je ne comprends pas cela: "Vous devez utiliser une fonction pour calculer où placer le pixel. Si votre programme n'a pas de fonction intégrée à cet effet, vous pouvez déduire le coût de sa mise en œuvre de votre score. " Quel pixel?
xnor

@xnor Il était initialement destiné à calculer comment dessiner le flocon de neige par pixel / caractère (le défi était à l'origine un défi ASCII). La plupart des gens n'utiliseront probablement que des lignes, je vais donc supprimer cela.

Peut-on dessiner le flocon de neige entier rempli?
xnor

Bien sûr. Ce commentaire doit être plus long.

Au n=7- delà , vous ne pouvez pas voir les triangles nouvellement ajoutés dans le flocon de neige sur un écran d'ordinateur. Y a-t-il un "meilleur effort" ici? Existe-t-il une résolution minimale pour les solutions basées sur les pixels?
xnor

Réponses:


7

Mathematica 72

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

n = 3

enter image description here

Merci pour alephalpha.


Bon travail. Jouez au golf avec deux personnages et vous obtenez la victoire!

@ Hosch250 Mis à jour, merci.
chyanog

Vous pouvez utiliser AnglePathdans Mathematica 10.1.
alephalpha

@chyaongGraphics@Line@AnglePath[Nest[Join@@({-1,2,-1,#}&/@#)&,{2,2,2},Input[]-1]Pi/3]
alephalpha

1
@alephalpha 73 caractères:ListLinePlot@AnglePath[Nest[Join@@({#,1,4,1}&/@#)&,{4,4,4},Input[]-1]π/3]
chyanog

15

MATLAB, 119 115

Dans une tournure inhabituelle des événements, j'ai constaté que ce programme fonctionnait mieux en le jouant au golf. Tout d'abord, il est devenu beaucoup plus rapide en raison de la vectorisation. Maintenant, il affiche une invite utile ~n:~rappelant à l'utilisateur la quantité à saisir!

Les sauts de ligne ne font pas partie du programme.

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

oest une chaîne arbitraire qui est égale à [0 2 4 0]modulo 6. e iπ / 3 élevé à ces puissances donne les sommets d'un triangle équilatéral dans le plan complexe. Le premier kronest utilisé pour faire une copie de la liste des points avec chacun dupliqué 4 fois. ~~oest le moyen pratique d'obtenir un vecteur de 4 unités. Trouve ensuite diff(P)le vecteur entre chaque paire de points consécutifs. Des multiples de ce vecteur (0, 1/3, (1 + e -iπ / 3 ) / 3 et 2/3) sont ajoutés à chacun des anciens points.


Uhm, pourriez-vous expliquer un peu plus comment ce code fonctionne? Je pensais que je connaissais du Matlab mais c'est ... de la folie ?? =)
flawr

@flawr J'ai ajouté quelques notes, est-ce que ça aide?
feersum

Merci beaucoup! Je vais garder à l'esprit cette astuce d'abus de cordes =)
flawr

9

T-SQL: 686 (hors formatage)

Pour SQL Server 2012+.

Même si ce ne sera jamais un concurrent, j'ai dû voir si je pouvais le faire en T-SQL. Parti pour l'approche de commencer par les trois bords initiaux, puis de revenir à travers chaque bord et de les remplacer par 4 bords pour chaque niveau. Enfin, tout est réuni en une seule géométrie pour le niveau spécifié pour @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

entrez la description de l'image ici entrez la description de l'image ici


Je ne savais pas qu'une telle magie pouvait être réalisée avec 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

Définit la fonction kavec un paramètre de niveau unique.

Éditer

Dans cet éditeur en ligne http://www.calormen.com/jslogo/, vous pouvez ajouter k readwordà l'invite de saisie, mais pour une raison quelconque, cette commande ne prend pas en charge l'abréviation standard rw.

La solution de 102 caractères ci-dessous fonctionne dans USBLogo avec une entrée standard comme spécifié dans la question. Cependant, le code a eu besoin de légères modifications car UCBLogo a un analyseur étrange. Il nécessite toet enddoit être dans des lignes distinctes et un espace avant :est requis, mais en revanche :sont facultatifs.

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

Comment exécutez-vous LOGO?
Beta Decay

@BetaDecay J'ai utilisé ceci: logo.twentygototen.org mais ce fut le premier que j'ai trouvé: calormen.com/jslogo Vous pouvez également installer 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

Comme auparavant, mais en noir et blanc, en versions non golfées (mais épurées) et golfées. Pas un gagnant, malgré le fait que le faire de cette façon évite d'avoir besoin d'un traitement spécial pour 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

entrez la description de l'image ici

REV 0

Selon la réponse du PO à @xnor, les flocons de neige remplis sont OK. Cette réponse a été inspirée par le commentaire de xnor. Les couleurs sont juste pour le plaisir et pour montrer la façon dont il est construit. Prenez un triangle (magenta dans ce cas) et superposez avec 6 triangles 1/3 de la base.

  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

entrez la description de l'image ici


1
J'aime à quoi il ressemble 7 d'entre eux ont fusionné.

@ hosch250 En effet, il me semble avoir "inventé" une nouvelle fractale dont la silhouette se trouve être un flocon de neige Koch, et si vous supprimez la partie magenta, vous vous retrouvez avec 6 flocons de neige Koch plus petits. La version golfée sera juste une silhouette noire unie, mais je laisserai cette image aussi.
Level River St

L'écrivez-vous BBC Basic ou BBC BASIC? J'opte pour ce dernier mais je ne sais pas si c'est correct ...
Beta Decay

2
@BetaDecay BASIC est un backronym pour le code d'instruction standard / symbolique polyvalent pour débutants. Le bit "Standard" est discutable car il existe de nombreuses variantes. en.wikipedia.org/wiki/BASIC . La plupart des variantes de BASIC préfèrent la version en majuscule, mais selon la page Wikipedia, Visual Basic préfère les minuscules. Je pense que BBC BASIC tel qu'expédié était en majuscules. J'utilise la version sur bbcbasic.co.uk/bbcwin/bbcwin.html . C'est en majuscule dans le site Web et l'IDE, donc je dirais que la version en majuscule est plus correcte. Mais je ne pense pas que cela compte beaucoup.
Level River St

Ahh d'accord, je vais continuer avec la version majuscule
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[]]

entrez la description de l'image ici

Clip bonus de variation de l'angle de la pièce centrale

entrez la description de l'image ici


6

Python 3 - 139

Utilise la bibliothèque graphique des tortues.

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

Cool. J'aime votre approche basée sur les chaînes pour trouver la forme avec pas plus de deux lignes de code! Mais tu ne peux pas vérifier "G">j, "Q"<jet utiliser fd(9/b)pour sauver 3 octets? De plus, vous pouvez éviter que les ifinstructions se multiplient, par exemple ("G">j)avec l'argument 9/bet les mettre toutes sur une seule ligne derrière for. Oh! Ensuite, vous pouvez même combiner rtet ltutiliser120*(...)-60*(...)
Falko

Cela semble rendre l'entrée flocon de neige Koch + 1. Une entrée de 1 devrait simplement être un triangle comme le montre l'image ci-dessus.

@Falko Merci pour toute cette aide!
Beta Decay

@ hosch250 Edited
Beta Decay

Maintenant, il ne dessine rien, et une entrée de 1 crée une erreur de division par 0.

4

Python 3, 117 octets

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)

Méthode:

  • La solution utilise les graphiques de tortues de Python.
  • n est input - 1
  • À partir de la chaîne, 0000nous joignons chaque caractère avec des 101 ntemps de manière itérative avec l' astuce eval (merci à @xnor pour cela).
  • Pour chaque caractère de la chaîne finale, nous tournons de 60 degrés à droite ou de 120 degrés à gauche en fonction de la valeur du caractère ( 1ou 0), puis avançons d'une longueur ( 99/3^n) qui garantit une taille similaire pour tous n.
  • Le dernier 0de la chaîne sera inutile mais il redessine simplement la même ligne que le premier 0dessine.

Exemple de sortie pour input = 3:

koch


2

R: 240 175

Parce que j'essaie de comprendre R, voici une autre version. Il y a probablement de bien meilleures façons de le faire et je suis heureux de recevoir des conseils. Ce que j'ai fait semble très compliqué.

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

entrez la description de l'image ici


2

Sage fwom youw gwave ...

Je savais que je voudrais essayer de l'implémenter dans Befunge-98 en utilisant TURT, mais je ne pouvais pas comprendre comment m'y prendre et je me suis assis dessus pendant plusieurs mois. Maintenant, ce n'est que récemment que j'ai trouvé un moyen de le faire sans utiliser d'auto-modification! Et donc...

Befunge-98 avec l'empreinte digitale 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

Voyons d'abord les détails de la mise en œuvre:

  • J'ai testé cela en utilisant CCBI 2.1 , dont l'implémentation de TURT (l'empreinte graphique de la tortue) fait I"imprimer" l'image dans un fichier SVG. Si vous l'exécutez dans CCBI sans l'argument de commande --turt-line=PATH, il apparaîtra sous la forme d'un fichier nommé CCBI_TURT.svg par défaut. C'est le plus proche que j'ai pu venir pour "imprimer une représentation graphique du flocon de neige à l'écran" avec les interprètes Funge disponibles que j'ai pu trouver. Peut-être qu'un jour il y aura un meilleur interprète qui aura un affichage graphique pour la tortue, mais pour l'instant ...
  • Il doit y avoir une nouvelle ligne à la fin pour que CCBI l'exécute sans se bloquer (cela est inclus avec le nombre de caractères). N'est-ce pas?

Fondamentalement, cela fonctionne en utilisant la pile comme une sorte de système en L de fortune et en l'étendant à la volée. À chaque passage, si le premier numéro de la pile est:

  • -2, puis il imprime et s'arrête;
  • -1, la tortue tourne dans le sens antihoraire de 60 degrés;
  • 0, il tourne de 120 degrés dans le sens des aiguilles d'une montre;
  • 1, il avance (de 15 pixels ici, mais vous pouvez le changer en modifiant le fsur la dernière ligne);
  • un certain nombre n qui est 2 ou plus, puis il est développé sur la pile n-1, -1, n-1, 0, n-1, -1, n-1.

Pour n = 10, ce processus prend beaucoup de temps (quelques minutes sur mon système), et le SVG résultant est de ~ 10 Mo et invisible lorsqu'il est affiché dans le navigateur, car vous ne pouvez pas régler la taille du pinceau à l'aide de TURT. IrfanView semble fonctionner correctement si vous avez les bons plugins. Je ne suis pas très familier avec SVG, donc je ne sais pas quelle est la méthode préférée pour visualiser ces fichiers (surtout quand ils sont vraiment gros).

Hé, au moins ça marche - ce qui, étant donné que c'est Befunge, est quelque chose dont on peut être reconnaissant en soi.


1

Python 2, 127 octets

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)

1
Merci pour avoir le 50 000e message ici.
Andrew
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.