Jouez au Chaos Game

28

Le Chaos Game est une méthode simple pour générer des fractales. Étant donné un point de départ, un rapport de longueur r et un ensemble de points 2D, procédez à plusieurs reprises comme suit:

  • Dans votre ensemble de points, choisissez-en un au hasard (uniformément).
  • Faites la moyenne de ce point et du dernier point tracé (ou du point de départ) en utilisant r et 1 - r comme poids (c.-à-d. R = 0 signifie que vous obtenez le point de départ, r = 1 signifie que vous obtenez le point aléatoire et r = 0,5 signifie que vous obtenir le point à mi-chemin entre les deux.)
  • Dessinez le point résultant.

Par exemple, si vous avez choisi les sommets d'un triangle équilatéral et r = 0,5 , les points tracés traceraient un triangle de Sierpinski:

entrez la description de l'image ici

Image trouvée sur Wikipédia

Vous devez écrire un programme ou une fonction qui "joue" le jeu du chaos pour créer une fractale.

Contribution

Vous pouvez écrire un programme ou une fonction et prendre les entrées suivantes via ARGV, STDIN ou l'argument de fonction:

  • Le nombre de points à tracer.
  • La coordonnée de départ (qui doit également être tracée!).
  • Le poids moyen r dans l'intervalle [0,1] .
  • Une liste de points à choisir.

Sortie

Vous pouvez effectuer un rendu à l'écran ou écrire un fichier image. Si le résultat est tramé, il doit être d'au moins 600 pixels de chaque côté, tous les points doivent être sur le canevas et au moins 75% de l'étendue horizontale et verticale de l'image doivent être utilisés pour les points (ceci afin d'éviter répond avec un seul pixel noir disant "c'est vraiment très loin"). Les axes x et y doivent être sur la même échelle (c'est-à-dire que la ligne de (0,0) à (1,1) doit être à un angle de 45 degrés) et chaque point tracé dans le jeu du chaos doit être représenté comme un seul pixel (si votre méthode de traçage anticrénelage le point, il peut être réparti sur 2x2 pixels).

Les couleurs sont votre choix, mais vous avez besoin d'au moins deux couleurs distinctes: une pour l'arrière-plan et une pour les points tracés pendant le jeu du chaos. Vous pouvez mais ne devez pas tracer les points d'entrée.

Veuillez inclure trois exemples de résultats intéressants dans votre réponse.

Notation

Il s'agit du code golf, donc la réponse la plus courte (en octets) l'emporte.

Modifier: vous n'avez plus besoin de tracer les points d'entrée, car ils ne sont de toute façon pas vraiment visibles en tant que pixels uniques.

Martin Ender
la source
Que signifie " chaque point tracé ... doit être représenté comme un seul pixel "? Est-ce a) qu'aucun anti-crénelage ne doit être utilisé; ou b) que le nombre de points dans la deuxième couleur doit être égal au premier élément de l'entrée? Notez que b) est impossible à garantir à moins que la procédure d'itération ait un test pour "Ce pixel coïncide-t-il avec un précédemment tracé?", Parce que si le sélecteur de nombre aléatoire sélectionne le même point suffisamment de fois dans une rangée, la position convergera vers ce point.
Peter Taylor
@PeterTaylor Il était destiné à éviter que les gens ne tracent de gros points comme les points (comme Mathematica le fait par défaut), mais j'ai déjà remarqué que l'anti-aliasing pose des problèmes pour garantir des pixels uniques dans la réponse de Soham. Je pense que je vais assouplir ceci à "ne doit pas être plus grand que 2x2 pixels", ce qui devrait couvrir tous les problèmes d'anti-aliasing.
Martin Ender
Je pense que j'ai mal compris quelque chose: vous prenez toujours la «moyenne» du dernier point que vous avez tracé et un point aléatoire de la liste actuelle. Ensuite, vous ajoutez ce nouveau point à la liste. Est-ce exact? Il semble que si vous avez beaucoup de points dans un «coin», vous en obtiendrez beaucoup plus, mais il est peu probable de sortir de ce nuage - au moins mon code «converge» toujours assez rapidement vers des points qui sont trop proches les uns des autres pour vraiment améliorer l'image.
flawr
1
@flawr non, vous n'ajoutez pas le nouveau point à la liste. La liste est fixe - l'algorithme ne se soucie que du dernier point tracé, pas de ceux qui le précèdent.
Nathaniel
Merci, cela explique beaucoup, devrait peut-être être clarifié dans la question.
flawr

Réponses:

8

Mathematica, 89

f[n_,s_,r_,p_]:=Graphics@{AbsolutePointSize@1,Point@NestList[#-r#+r RandomChoice@p&,s,n]}

f[10000, {0, 0}, .5, {{-(1/2), Sqrt[3]/2}, {-(1/2), -(Sqrt[3]/2)}, {1, 0}}]

Graphiques Mathematica

Comment ça marche

Dans Mathematica, la Graphics[]fonction produit des graphiques évolutifs, vous la restituez à la taille souhaitée en faisant simplement glisser les coins de l'image. En fait, la taille initiale de tous les graphiques affichés est un paramètre ".ini" que vous pouvez définir à 600 ou à toute autre valeur que vous souhaitez. Il n'est donc pas nécessaire de faire quoi que ce soit de spécial pour l'exigence 600x600.

La AbsolutePointSize[]chose spécifie que la taille du point ne sera pas modifiée en agrandissant la taille de l'image.

La construction de base est

 NestList[#-r#+r RandomChoice@p&,s,n]

ou en pseudo-code non golfé:

 NestList[(previous point)*(1-r) + (random vertex point)*(r), (start point), (iterations)]

Il construit récursivement une liste à partir de (start point)et applique la fonction (vectorielle) du premier argument à chaque point successif, pour finalement retourner la liste de tous les points calculés à tracer parPoint[]

Quelques exemples d'auto-réplication:

Grid@Partition[Table[
   pts = N@{Re@#, Im@#} & /@ Table[E^(2 I Pi r/n), {r, 0, n - 1}];
   Framed@f[10000, {0, 0}, 1/n^(1/n), pts], {n, 3, 11}], 3]

Graphiques Mathematica

Dr. belisarius
la source
@ MartinBüttner Instructions for testing this answer without Mathematica installed:1) Téléchargez -le à partir de pastebin et enregistrez-le sous * .CDF 2) Téléchargez et installez l' environnement CDF gratuit de Wolfram Research à (pas un petit fichier). Prendre plaisir. Dites-moi si ça marche!
Dr belisarius
Votre version ne golfed pas tout à fait le travail (au moins sur V10): vous devez passer autour #rde r#de sortir sans espace ou *entre les deux.
Martin Ender
@ MartinBüttner Curieux! Cela fonctionne comme un charme sur v9 (je n'ai pas encore de v10). Quoi qu'il en soit, j'ai (aveuglément) échangé le #et r.
Dr belisarius
Ah, c'est une nouvelle fonctionnalité. Vous pouvez maintenant appliquer des fonctions aux associations, auquel cas vous obtenez des paramètres nommés accessibles par #key. Je suis sûr que cela vous sera utile. :)
Martin Ender
8

Java: 246 253 447

En fonction m():

void m(float[]a){new java.awt.Frame(){public void paint(java.awt.Graphics g){int i=0,x=i,y=i,v;for(setSize(832,864),x+=a[1],y+=a[2];i++<=a[0];v=a.length/2-2,v*=Math.random(),x+=(a[v+=v+4]-x)*a[3],y+=(a[v+1]-y)*a[3])g.drawLine(x,y,x,y);}}.show();}

Sauts de ligne (dans un programme pour montrer l'utilisation):

class P{
    public static void main(String[]a){
        new P().m(new float[]{1000000,            // iterations
                              416,432,            // start
                              0.6f,               // r
                              416,32,16,432,      // point list...
                              416,832,816,432,
                              366,382,366,482,
                              466,382,466,482});
    }

    void m(float[]a){
        new java.awt.Frame(){
            public void paint(java.awt.Graphics g){
                int i=0,x=i,y=i,v;
                for(setSize(832,864),x+=a[1],y+=a[2];
                    i++<=a[0];
                    v=a.length/2-2,v*=Math.random(),
                    x+=(a[v+=v+4]-x)*a[3],
                    y+=(a[v+1]-y)*a[3])
                    g.drawLine(x,y,x,y);
            }
        }.show();
    }
}

Le dessin des points d'entrée a été supprimé des exigences (oui 80 octets!). Ils sont toujours affichés dans les anciennes captures d'écran ci-dessous, mais n'apparaîtront pas si vous l'exécutez. Voir l'historique des révisions si vous êtes intéressé.

Les entrées sont données sous forme de tableau de flottants. La première est des itérations, les deux suivantes commencent x y. La quatrième est r, et enfin vient la liste des coordonnées, à la x1 y1 x2 y2 ...mode.

Étoile de ninja

1000000 400 400 0.6 400 0 0 400 400 800 800 400 350 350 350 450 450 350 450 450

entrez la description de l'image ici

Traverser

1000000 400 400 0.8 300 0 500 0 500 300 800 300 800 500 500 500 500 800 300 800 300 500 0 500 0 300 300 300

entrez la description de l'image ici

Octochains

1000000 400 400 0.75 200 0 600 0 800 200 800 600 600 800 200 800 0 600 0 200

entrez la description de l'image ici

Géobits
la source
cela ne fonctionne pas sur mon ordinateur, et java se plaint showest obsolète
fier haskeller
@proudhaskeller show() est obsolète, mais il fonctionne toujours. Lorsque vous dites "ne fonctionne pas", qu'est-ce que cela signifie? Si vous n'avez pas Java 8, vous devrez au moins ajouter un finalà String[]adans main.
Geobits
Portez votre réponse au traitement et coupez 100 caractères.
user12205
1
@ace Nice. Vous pouvez le faire avec à peu près n'importe quel golf Java pour la sortie graphique, mais j'aime bien que ce soit exactement 100 caractères: D
Geobits
7

JavaScript (E6) + Html 173 176 193 193

Edit: grosse coupe, grâce à William Barbosa

Edit: 3 octets de moins, grâce à DocMax

173 octets comptant la fonction et l'élément canvas nécessaires pour afficher la sortie.

Testez l' enregistrement en tant que fichier html et ouvrez-le dans FireFox.

JSFiddle

Agréable


Masque


Neige


Tapis


<canvas id=C>
<script>
F=(n,x,y,r,p)=>{
  for(t=C.getContext("2d"),C.width=C.height=600;n--;x-=(x-p[i])*r,y-=(y-p[i+1])*r)
    i=Math.random(t.fillRect(x,y,1,1))*p.length&~1      
}
F(100000, 300, 300, 0.66, [100,500, 500,100, 500,500, 100,100, 300,150, 150,300, 300,450, 450,300]) // Function call, not counted
</script>
edc65
la source
1
<canvas id=C><script>F=(n,x,y,r,p)=>{t=C.getContext("2d"),C.width=C.height=600;for(;n--;)t.fillRect(x,y,1,1),i=Math.random()*p.length&~1,x-=(x-p[i])*r,y-=(y-p[i+1])*r}</script>est de 176 octets, je n'ai pas compris votre compte
William Barbosa
@WilliamBarbosa mon décompte est correct d'après ma réponse. Avec vos indices, cela s'améliore - merci!
edc65
1
Vous pouvez raser deux autres si vous déplacez l'initialisation de la taille et y mettez à jour dans l' forappel:for(C.width=C.height=600;n--;y-=(y-p[i+1])*r)
DocMax
6

Python - 200 189

import os,random as v
def a(n,s,r,z):
    p=[255]*360000
    for i in[1]*(n+1):
        p[600*s[0]+s[1]]=0;k=v.choice(z);s=[int(k[i]*r+s[i]*(1-r))for i in(0,1)]
    os.write(1,b'P5 600 600 255 '+bytes(p))

Prend l'entrée comme arguments de fonction dans a, écrit le résultat dans stdout en tant que fichier pgm. nest des itérations, sest le point de départ, rest r et zest la liste des points d'entrée.

Modifier: ne dessine plus les points d'entrée en gris.

Sorties intéressantes:

entrez la description de l'image ici

Iterations: 100000
Starting Point: (200, 200)
r: 0.8
Points: [(0, 0), (0, 599), (599, 0), (599, 599), (300, 300)]

entrez la description de l'image ici

Iterations: 100000
Starting Point: (100, 300)
r: 0.6
Points: [(0, 0), (0, 599), (599, 0), (300, 0), (300, 300), (0, 300)]

entrez la description de l'image ici

Iterations: 100000
Starting Point: (450, 599)
r: 0.75
Points: [(0, 0), (0, 300), (0, 599), (300, 0), (599, 300), (150, 450)]
faubi
la source
Quelques sauvegardes de caractères Python courantes: Les valeurs initiales comme p=[255]*360000peuvent aller comme paramètres optionnels à la fonction; le corps d'une boucle for peut tous aller sur la même ligne s'il n'a pas de flux de contrôle; vous pouvez raser les parens au [1]*(n+1)fur et à mesure [1]*-~n; puisque vous n'utilisez pas idans la boucle for externe, il est plus court d'exécuter le code ncomme exec"code;"*n); Je pense que les parens for i in(0,1)peuvent être supprimés.
xnor
6

SuperCollider - 106

SuperCollider est un langage pour générer de la musique, mais il peut faire des graphiques à la rigueur.

f={|n,p,r,l|Window().front.drawHook_({{Pen.addRect(Rect(x(p=l.choose*(1-r)+(p*r)),p.y,1,1))}!n;Pen.fill})}

J'ai utilisé des raccourcis de syntaxe obscurs pour économiser quelques octets - une version plus lisible et plus efficace en mémoire est

f={|n,p,r,l|Window().front.drawHook_({n.do{Pen.addRect(Rect(p.x,p.y,1,1));p=l.choose*(1-r)+(p*r)};Pen.fill})}

à 109 caractères.

Comme avec l'exemple Mathematica, vous devez redimensionner manuellement la fenêtre pour obtenir 600x600 pixels. Vous devez attendre qu'il redessine lorsque vous faites cela.

Cela génère un triangle de Sierpinsky de base (non affiché car vous l'avez déjà vu)

f.(20000,100@100,0.5,[0@600,600@600,300@0])

Cela fait une sorte de chose de type pentagone Sierpinsky:

f.(100000,100@100,1-(2/(1+sqrt(5))),{|i| (sin(i*2pi/5)+1*300)@(1-cos(i*2pi/5)*300)}!5)

entrez la description de l'image ici

La même chose avec 6 points laisse un flocon de neige Koch inversé au milieu:

f.(100000,100@100,1/3,{|i| (sin(i*2pi/6)+1*300)@(1-cos(i*2pi/6)*300)}!6)

entrez la description de l'image ici

Enfin, voici un riff sur les pyramides 3D de la réponse d'Ace. (Notez que j'ai utilisé l'un des points deux fois, pour obtenir l'effet d'ombrage.)

f.(150000,100@100,0.49,[300@180, 0@500,0@500,350@400,600@500,250@600])

entrez la description de l'image ici

Nathaniel
la source
6

Python, 189 183 175

Édition: correction du rapport r inversé et passage à l'image noir et blanc afin d'économiser quelques octets.

Prend le nombre de points comme n, le premier point comme p, le rapport comme ret la liste des points comme l. A besoin du module Oreiller.

import random,PIL.Image as I
s=850
def c(n,p,r,l):
    i=I.new('L',(s,s));x,y=p;
    for j in range(n):w,z=random.choice(l);w*=r;z*=r;x,y=x-x*r+w,y-y*r+z;i.load()[x,s-y]=s
    i.show()

Exemples:

Je génère des points en cercle autour du centre de l'image

points = [(425+s*cos(a)/2, 425+s*sin(a)/2) for a in frange(.0, 2*pi, pi/2)]
c(1000000, (425, 425), 0.4, points)

entrez la description de l'image ici

Répétitions XOXO, en changeant simplement le rapport de 0,4 à 0,6

entrez la description de l'image ici

Une sorte de flocon de neige

stars = [(425+s*cos(a)/2,425+s*sin(a)/2) for a in frange(.0,2*pi, pi/4)]
c(1000000, (425, 425), 0.6, stars)

entrez la description de l'image ici

les internets sont en catz
la source
J'sais sur la fixation de l'arrière r chose, mais vous pouvez économiser un peu de caractères en faisant ce un programme à l' aide n,p,r,l=input(). Vous pouvez également supprimer les crochets des *=opérations et de l'utilisation import random as R.
FryAmTheEggman
@FryAmTheEggman Malheureusement, la correction de ma réponse invalide l'optimisation sur *=:(. La inputchose serait bien très désagréable à travailler, et l'importation est actuellement la forme la plus concise possible (ou ai-je oublié quelque chose?).
internets sont faits du catz
Je suis presque sûr que la ligne peut être import random as R,PIL.Image as Iet random.choicepeut l'être R.choice. Oui, l'utilisation de l'entrée est boiteuse, mais vous pouvez utiliser la version de la fonction pour tester et publier input()celle pour un meilleur score !! 1! : P
FryAmTheEggman
Oh, je viens de remarquer que la définition aléatoire enregistre en fait 0 caractère. Oups: S Quoi qu'il en soit, j'ai également réalisé que les mathématiques sont votre ami: y=x*(1-r)+w== y=x-x*r-w.
FryAmTheEggman
@FryAmTheEggman c'était mon point: p. Mais merci pour les maths.
internets sont en catz
4

JavaScript (407) (190)

Je suis heureux d'avoir des commentaires sur mon script et sur le golf car je ne suis pas à l'aise avec JS =) (N'hésitez pas à l'utiliser / à le modifier pour votre propre soumission!)

Lecture de l'entrée (pour être comparable à l' entrée de l' edc65 , je ne compte pas l'entrée.):

p=prompt;n=p();[x,y]=p().split(',');r=p();l=p().split(';').map(e=>e.split(','));

Configuration et calcul du canevas

d=document;d.body.appendChild(c=d.createElement('canvas'));c.width=c.height=1000;c=c.getContext('2d');
for(;n--;c.fillRect(x,y,2,2),[e,f]= l[Math.random()*l.length|0],x-=x*r-e*r,y-=y*r-f*r);

Un peu plus non golfé (y compris un exemple d'entrée où les invites d'entrée réelles sont juste commentées, donc prêtes à l'emploi):

p=prompt;
n=p('n','4000');
[x,y]=p('start','1,1').split(',');
r=p('r','0.5');
l=p('list','1,300;300,1;300,600;600,300').split(';').map(e=>e.split(','));d=document;
d.body.appendChild(c=d.createElement('canvas'));
c.width=c.height=1000;c=c.getContext('2d');
for(;n--;c.fillRect(x,y,2,2),[e,f]= l[Math.random()*l.length|0],x-=x*r-e*r,y-=y*r-f*r);

Exemples

for(k = 0; k<50; k++){
rad = 10;
l.push([350+rad*k*Math.cos(6.28*k/10),350+rad*k*Math.sin(6.28*k/10)]);
}
r = 1.13;

entrez la description de l'image ici

r = 0.5;list = [[1,1],[300,522],[600,1],[300,177]];

entrez la description de l'image ici

r = 0.5
list = [[350+350*Math.sin(6.28*1/5),350+350*Math.cos(6.28*1/5)],
[350+350*Math.sin(6.28*2/5),350+350*Math.cos(6.28*2/5)],
[350+350*Math.sin(6.28*3/5),350+350*Math.cos(6.28*3/5)],
[350+350*Math.sin(6.28*4/5),350+350*Math.cos(6.28*4/5)],
[350+350*Math.sin(6.28*5/5),350+350*Math.cos(6.28*5/5)],


[350+90*Math.sin(6.28*1.5/5),350+90*Math.cos(6.28*1.5/5)],
[350+90*Math.sin(6.28*2.5/5),350+90*Math.cos(6.28*2.5/5)],
[350+90*Math.sin(6.28*3.5/5),350+90*Math.cos(6.28*3.5/5)],
[350+90*Math.sin(6.28*4.5/5),350+90*Math.cos(6.28*4.5/5)],
[350+90*Math.sin(6.28*5.5/5),350+90*Math.cos(6.28*5.5/5)]];

entrez la description de l'image ici

flawr
la source
Lesquelles voulez-vous dire?
flawr
Oh merci de me l'avoir dit, je vais bientôt mettre à jour la soumission!
flawr
Vous avez lié ma réponse, mais je compte la configuration de la toile. Je ne compte simplement pas la seule ligne appelant la fonction. De belles images quand même, surtout la première.
edc65
Ah, je ne l'ai pas remarqué, je voulais juste le rendre `` comparable '', mais c'est difficile quand j'essaie de compter uniquement sur JS =) @ MartinBüttner Mise à jour, maintenant que je l'ai compris de la bonne façon, j'ai pu supprimer une grande partie les ordures =)
flawr
3

Traitement, 153

Porté la réponse Java de @Geobits au traitement et a fait un peu plus de golf, ce qui a entraîné une réduction de 100 caractères. J'avais initialement l'intention d'animer le processus, mais les contraintes d'entrée sont trop dures à ce sujet (Processing n'a pas stdin ou argv, ce qui signifie que je dois écrire ma propre fonction au lieu d'utiliser la draw()boucle native de Processing ).

void d(float[]a){int v;size(600,600);for(float i=0,x=a[1],y=a[2];i++<a[0];v=(int)random(a.length/2-2),point(x+=(a[v*2+4]-x)*a[3],y+=(a[v*2+5]-y)*a[3]));}

Programme complet avec sauts de ligne:

void setup() {
  d(new float[]{100000,300,300,.7,0,600,600,0,600,600,0,0,400,400,200,200,400,200,200,400}); 
}
void d(float[]a){
  int v;
  size(600,600);
  for(float i=0,x=a[1],y=a[2];
      i++<a[0];
      v=(int)random(a.length/2-2),point(x+=(a[v*2+4]-x)*a[3],y+=(a[v*2+5]-y)*a[3]));
}

Le programme ci-dessus donne à Crosses: entrez la description de l'image ici

d(new float[]{100000,300,300,.65,142,257,112,358,256,512,216,36,547,234,180,360}); 

Cela donne aux Pyramides: entrez la description de l'image ici

d(new float[]{100000,100,500,.5,100,300,500,100,500,500});

Cela donne le triangle de Sierpinski: entrez la description de l'image ici

user12205
la source
4
J'adore l'effet 3D des pyramides. :)
Martin Ender
1

"Implémentation de référence" non golfée, Python

Mise à jour : beaucoup, beaucoup plus rapide (par ordre de grandeur)

Découvrez le shell interactif!

Modifiez le fichier et définissez- interactivele True, puis effectuez l'une des opérations suivantes:

polygon numberOfPoints numeratorOfWeight denominatorOfWeight startX startY numberOfSides génère, enregistre et affiche un polygone.

points numberOfPoints numeratorOfWeight denominatorOfWeight startX startY point1X point1Y point2X point2Y ... fait ce que la spécification demande.

entrez la description de l'image ici

import matplotlib.pyplot as plt
import numpy as np
from fractions import Fraction as F
import random
from matplotlib.colors import ColorConverter
from time import sleep
import math
import sys
import cmd
import time

def plot_saved(n, r, start, points, filetype='png', barsize=30, dpi=100, poly=True, show=False):
    printed_len = 0

    plt.figure(figsize=(6,6))
    plt.axis('off')

    start_time = time.clock()
    f = F.from_float(r).limit_denominator()

    spts = []
    for i in range(len(points)):
        spts.append(tuple([round(points[i].real,1), round(points[i].imag,1)]))

    if poly:
        s = "{}-gon ({}, r = {}|{})".format(len(points), n, f.numerator, f.denominator)
    else:
        s = "{} ({}, r = {}|{})".format(spts, n, f.numerator, f.denominator) 

    step = math.floor(n / 50)

    for i in range(len(points)):
        plt.scatter(points[i].real, points[i].imag, color='#ff2222', s=50, alpha=0.7)

    point = start
    t = time.clock()

    xs = []
    ys = []

    for i in range(n+1):
        elapsed = time.clock() - t
        #Extrapolation
        eta = (n+1-i)*(elapsed/(i+1))
        printed_len = rewrite("{:>29}: {} of {} ({:.3f}%) ETA: {:.3f}s".format(
                s, i, n, i*100/n, eta), printed_len)
        xs.append(point.real)
        ys.append(point.imag)
        point = point * r + random.choice(points) * (1 - r)

    printed_len = rewrite("{:>29}: plotting...".format(s), printed_len)
    plt.scatter(xs, ys, s=0.5, marker=',', alpha=0.3)

    presave = time.clock()
    printed_len = rewrite("{:>29}: saving...".format(s), printed_len)
    plt.savefig(s + "." + filetype, bbox_inches='tight', dpi=dpi)

    postsave = time.clock()
    printed_len = rewrite("{:>29}: done in {:.3f}s (save took {:.3f}s)".format(
                            s, postsave - start_time, postsave - presave),
                            printed_len)

    if show:
        plt.show()
    print()
    plt.clf()

def rewrite(s, prev):
    spaces = prev - len(s)
    sys.stdout.write('\r')
    sys.stdout.write(s + ' '*(0 if spaces < 0 else spaces))
    sys.stdout.flush()
    return len(s)

class InteractiveChaosGame(cmd.Cmd):
    def do_polygon(self, args):
        (n, num, den, sx, sy, deg) = map(int, args.split())
        plot_saved(n, (num + 0.0)/den, np.complex(sx, sy), list(np.roots([1] + [0]*(deg - 1) + [-1])), show=True)

    def do_points(self, args):
        l = list(map(int, args.split()))
        (n, num, den, sx, sy) = tuple(l[:5])
        l = l[5:]
        points = []
        for i in range(len(l)//2):
            points.append(complex(*tuple([l[2*i], l[2*i + 1]])))
        plot_saved(n, (num + 0.0)/den, np.complex(sx, sy), points, poly=False, show=True)

    def do_pointsdpi(self, args):
        l = list(map(int, args.split()))
        (dpi, n, num, den, sx, sy) = tuple(l[:6])
        l = l[6:]
        points = []
        for i in range(len(l)//2):
            points.append(complex(*tuple([l[2*i], l[2*i + 1]])))
        plot_saved(n, (num + 0.0)/den, np.complex(sx, sy), points, poly=False, show=True, dpi=dpi)

    def do_default(self, args):
        do_generate(self, args)

    def do_EOF(self):
        return True

if __name__ == '__main__':
    interactive = False
    if interactive:
        i = InteractiveChaosGame()
        i.prompt = ": "
        i.completekey='tab'
        i.cmdloop()
    else:
        rs = [1/2, 1/3, 2/3, 3/8, 5/8, 5/6, 9/10]
        for i in range(3, 15):
            for r in rs:
                plot_saved(20000, r, np.complex(0,0), 
                            list(np.roots([1] + [0] * (i - 1) + [-1])), 
                            filetype='png', dpi=300)
Soham Chowdhury
la source
Sans exécuter cela, je n'ai aucune idée de ce que signifie génial . Peut-être pourriez-vous expliquer ou montrer quelques images de ce qui le différencie des plus courtes?
Geobits
@Geobits modifié pour inclure la clause de non-responsabilité et l'image :)
Soham Chowdhury
4
Je préférerais que vous incluiez cela sous un titre distinct (par exemple, Implémentation de référence non golfée) dans votre autre réponse, car publier uniquement du code non golfé n'est techniquement "pas une réponse".
Martin Ender
-2

Python (202 caractères)

Prend le nombre de points comme n, le poids moyen comme r, le point de départ comme a tuple set la liste des points comme une liste de XY tupleappelés l.

import random as v,matplotlib.pyplot as p
def t(n,r,s,l):
 q=complex;s=q(*s);l=[q(*i)for i in l];p.figure(figsize=(6,6))
 for i in range(n):p.scatter(s.real,s.imag,s=1,marker=',');s=s*r+v.choice(l)*(1-r)
 p.show()
Soham Chowdhury
la source
@ MartinBüttner Le fait que je prenne un type d'entrée spécifique correspond-il à la spécification?
Soham Chowdhury du
1
De plus, sur ma machine, le résultat n'est pas de 600x600 pixels, x et y ont des échelles de longueur différentes et les points couvrent plus de 1 pixel.
Martin Ender