Juega el juego del caos

28

El Juego del Caos es un método simple para generar fractales. Dado un punto de partida, una relación de longitud r y un conjunto de puntos 2D, haga lo siguiente repetidamente:

  • De su conjunto de puntos, elija uno al azar (uniformemente).
  • Promedie ese punto y el último punto dibujado (o el punto de partida) usando r y 1 - r como los pesos (es decir, r = 0 significa que obtiene el punto de partida, r = 1 significa que obtiene el punto aleatorio y r = 0.5 significa que obtener el punto a medio camino.)
  • Dibuja el punto resultante.

Por ejemplo, si seleccionó los vértices de un triángulo equilátero yr = 0.5 , los puntos trazados trazarían un triángulo de Sierpinski:

ingrese la descripción de la imagen aquí

Imagen encontrada en Wikipedia

Debes escribir un programa o función que "juegue" el juego del caos para crear un fractal.

Entrada

Puede escribir un programa o una función, y tomar las siguientes entradas a través de ARGV, STDIN o argumento de función:

  • El número de puntos para trazar.
  • La coordenada de inicio (¡que también debe trazarse!).
  • El peso promedio r en el intervalo [0,1] .
  • Una lista de puntos para elegir.

Salida

Puede renderizar en pantalla o escribir un archivo de imagen. Si el resultado está rasterizado, debe tener al menos 600 píxeles en cada lado, todos los puntos deben estar en el lienzo y al menos el 75% de la extensión horizontal y vertical de la imagen debe usarse para los puntos (esto es para evitar responde con un solo píxel negro que dice "está muy alejado"). La x e y eje debe estar en la misma escala (es decir la línea a partir de (0,0) a (1,1) deben estar en un ángulo de 45 grados) y cada punto representado en el juego del caos debe ser representado como una sola píxel (si su método de trazado suaviza el punto, puede extenderse en 2x2 píxeles).

Los colores son su elección, pero necesita al menos dos colores distinguibles: uno para el fondo y otro para los puntos trazados durante el juego del caos. Puede pero no tiene que trazar los puntos de entrada.

Incluya tres resultados de ejemplo interesantes en su respuesta.

Tanteo

Este es el código de golf, por lo que gana la respuesta más corta (en bytes).

Editar: ya no necesita trazar los puntos de entrada, ya que de todos modos no son realmente visibles como píxeles individuales.

Martin Ender
fuente
¿Qué significa " cada punto trazado ... debe representarse como un solo píxel "? ¿Es a) que no se debe usar anti-aliasing; o b) que el número de puntos en el segundo color debe ser igual al primer elemento de la entrada? Tenga en cuenta que b) es imposible de garantizar a menos que el procedimiento de iteración tenga una prueba para "¿Este píxel coincide con uno previamente trazado?", Porque si el selector de números aleatorios selecciona el mismo punto suficientes veces seguidas, la posición convergerá a ese punto.
Peter Taylor
@PeterTaylor Tenía la intención de evitar que las personas dibujaran puntos grandes como los puntos (como lo hace Mathematica de manera predeterminada), pero ya me di cuenta de que el suavizado causa algunos problemas para garantizar píxeles únicos en la respuesta de Soham. Creo que relajaré esto a "no debe ser mayor que 2x2 píxeles", lo que debería cubrir todos los problemas de suavizado.
Martin Ender
Creo que entendí mal algo: siempre tomas la 'media' del último punto que trazaste y un punto aleatorio de la lista actual. Luego agrega ese nuevo punto a la lista. ¿Es eso correcto? Parece que si tiene muchos puntos en una 'esquina', obtendrá muchos más allí, pero es poco probable que salga de esa nube; al menos mi código siempre 'converge' bastante rápido a puntos que están demasiado cerca el uno del otro para Realmente mejorar la imagen.
flawr
1
@flawr no, no agrega el nuevo punto a la lista. La lista es fija: el algoritmo solo se preocupa por el último punto que se trazó, no por los anteriores.
Nathaniel
Gracias, eso explica mucho, quizás debería aclararse en la pregunta.
flawr

Respuestas:

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

Gráficos de Mathematica

Cómo funciona

En Mathematica, la Graphics[]función produce gráficos escalables, puede representarlos al tamaño que desee simplemente arrastrando las esquinas de la imagen. De hecho, el tamaño inicial de todos los gráficos mostrados es una configuración ".ini" que puede establecer en 600 o en cualquier otro valor que desee. Por lo tanto, no hay necesidad de hacer nada especial para el requisito de 600x600.

La AbsolutePointSize[]cosa especifica que el tamaño en puntos no se modificará ampliando el tamaño de la imagen.

La construcción central es

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

o en pseudocódigo no golfizado:

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

Está construyendo recursivamente una lista a partir de (start point)y aplicando la función (vectorial) en el primer argumento a cada punto sucesivo, finalmente devolviendo la lista de todos los puntos calculados para ser graficados porPoint[]

Algunos ejemplos de autorreplicación:

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]

Gráficos de Mathematica

Dr. belisario
fuente
@ MartinBüttner Instructions for testing this answer without Mathematica installed:1) Descargue esto desde pastebin y guárdelo como * .CDF 2) Descargue e instale el entorno CDF gratuito de Wolfram Research en (no es un archivo pequeño). Disfrutar. ¡Dime si funciona!
Dr. belisario
Su versión golfed no acaba de trabajo (al menos en V10): hay que cambiar todo #rpara r#salir de allí sin un espacio o *en el medio.
Martin Ender
@ MartinBüttner ¡Curioso! Funciona como un encanto en v9 (todavía no tengo v10). De todos modos, (ciegamente) cambié el #y r.
Dr. belisario
Ah, es una nueva característica. Ahora puede aplicar funciones a asociaciones, en cuyo caso obtendrá parámetros con nombre a los que puede acceder #key. Estoy seguro de que será útil. :)
Martin Ender
8

Java: 246 253 447

Como una función 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();}

Saltos de línea (dentro de un programa para mostrar el uso):

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

Se eliminaron los puntos de entrada de dibujo de los requisitos (¡yay 80 bytes!). Todavía se muestran en las capturas de pantalla anteriores a continuación, pero no se mostrarán si lo ejecuta. Ver historial de revisiones si está interesado.

Las entradas se dan como una matriz de flotadores. La primera es iteraciones, las dos siguientes están comenzando x y. El cuarto es r, y el último viene la lista de coordenadas, de x1 y1 x2 y2 ...moda.

Estrella ninja

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

ingrese la descripción de la imagen aquí

Cruzar

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

ingrese la descripción de la imagen aquí

Octocadenas

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

ingrese la descripción de la imagen aquí

Geobits
fuente
esto no funciona en mi computadora, y Java se queja showestá en desuso
orgulloso haskeller
@proudhaskeller show() está en desuso, pero aún funciona. Cuando dices "no funciona", ¿qué significa eso? Si no tiene Java 8, necesitará agregar un finalto String[]aen main al menos.
Geobits
Portó su respuesta a Processing y cortó 100 caracteres.
user12205
1
@ace Nice. Puede hacer eso con casi cualquier golf Java para salida gráfica, pero me gusta que sean exactamente 100 caracteres: D
Geobits
7

JavaScript (E6) + Html 173176193

Editar: gran corte, gracias a William Barbosa

Editar: 3 bytes menos, gracias a DocMax

173 bytes contando la función y el elemento de lienzo necesarios para mostrar la salida.

Prueba guardar como archivo html y abrir en Firefox.

JSFiddle

agradable


Máscara


Nieve


Alfombra


<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
fuente
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>tiene 176 bytes de longitud, no entendí tu conteo
William Barbosa
@WilliamBarbosa mi recuento es correcto según mi respuesta. Con tus pistas se pone mejor, ¡gracias!
edc65
1
Puede eliminar dos más si mueve la inicialización del tamaño y actualiza la forllamada: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))

Toma la entrada como argumentos de función en a, escribe el resultado en stdout como archivo pgm. nes iteraciones, ses el punto de partida, res r, y zes una lista de puntos de entrada.

Editar: ya no dibuja puntos de entrada en gris.

Resultados interesantes:

ingrese la descripción de la imagen aquí

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

ingrese la descripción de la imagen aquí

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

ingrese la descripción de la imagen aquí

Iterations: 100000
Starting Point: (450, 599)
r: 0.75
Points: [(0, 0), (0, 300), (0, 599), (300, 0), (599, 300), (150, 450)]
faubi
fuente
Algunos caracteres comunes de Python se guardan: los valores iniciales como p=[255]*360000pueden ir como parámetros opcionales a la función; el cuerpo de un bucle for puede ir en la misma línea si no tiene flujo de control; puedes afeitar a los pans de [1]*(n+1)as [1]*-~n; como no se usa ien el bucle for externo, es más corto ejecutar el código las nveces como exec"code;"*n); Creo que los padres for i in(0,1)pueden ser eliminados.
xnor
6

SuperCollider - 106

SuperCollider es un lenguaje para generar música, pero puede hacer gráficos en caso de necesidad.

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

He usado algunos métodos abreviados de sintaxis oscuros para guardar unos pocos bytes; una versión más legible y más eficiente en memoria es

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

a 109 caracteres.

Al igual que con el ejemplo de Mathematica, debe cambiar el tamaño manualmente de la ventana para obtener 600x600 píxeles. Tienes que esperar a que se vuelva a dibujar cuando hagas esto.

Esto genera un triángulo básico de Sierpinsky (no se muestra porque lo has visto antes)

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

Esto hace una especie de cosa tipo pentágono Sierpinsky:

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

ingrese la descripción de la imagen aquí

Lo mismo con 6 puntos deja un copo de nieve Koch invertido en el medio:

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

ingrese la descripción de la imagen aquí

Finalmente, aquí hay un riff en las pirámides 3D de la respuesta de as. (Tenga en cuenta que he usado uno de los puntos dos veces, para obtener el efecto de sombreado).

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

ingrese la descripción de la imagen aquí

Nathaniel
fuente
6

Python, 189 183 175

Editar: corrigió la relación r inversa y cambió a la imagen en blanco y negro para guardar algunos bytes.

Toma el número de puntos como n, primer punto como p, relación como ry lista de puntos como l. Necesita el módulo Pillow.

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

Ejemplos:

Estoy generando puntos en círculo alrededor del centro de la imagen.

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)

ingrese la descripción de la imagen aquí

Repeticiones XOXO, solo cambiando la relación de 0.4 a 0.6

ingrese la descripción de la imagen aquí

Algún tipo de copo de nieve

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)

ingrese la descripción de la imagen aquí

las interconexiones están hechas de catz
fuente
No sé sobre la fijación de las revés r cosa, pero le puede ahorrar un buen número de caracteres al hacer esto usando un programa n,p,r,l=input(). También puede eliminar los corchetes de las *=operaciones y el uso import random as R.
FryAmTheEggman
@FryAmTheEggman Por desgracia, la corrección de mis invalida la respuesta de optimización en *=. :( La inputcosa sería bueno ser muy desagradable para trabajar, y la importación en la actualidad es la forma más concisa posible (o he perdido algo?).
los Internet se hace de catz
Estoy bastante seguro de que la línea puede ser import random as R,PIL.Image as Iy luego random.choicepuede ser R.choice. Sí, el uso de la entrada es poco convincente, ¡pero puedes usar la versión de la función para probar y publicar la que tenga input()una mejor puntuación! : P
FryAmTheEggman
Oh, acabo de notar que definir aleatorio realmente guarda 0 caracteres. Oops: S De todos modos, también me di cuenta de que las matemáticas son tu amigo: y=x*(1-r)+w== y=x-x*r-w.
FryAmTheEggman
@FryAmTheEggman ese fue mi punto: p. Pero gracias por las matemáticas.
interconexiones están hechas de catz el
4

JavaScript (407) (190)

Estoy feliz de recibir cualquier comentario sobre mi script y sobre el golf, ya que no me siento cómodo con JS =) (¡Siéntase libre de usar esto / cambiarlo para su propio envío!)

Lectura de entrada (para ser comparable a la entrada de edc65 no cuento la entrada):

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

Configuración de lienzo y cálculo

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

Algo más descabellado (incluida una entrada de ejemplo donde las solicitudes de entrada reales solo se comentan, así que están listas para usar):

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

Ejemplos

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;

ingrese la descripción de la imagen aquí

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

ingrese la descripción de la imagen aquí

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

ingrese la descripción de la imagen aquí

falla
fuente
¿A cuáles te refieres?
flawr
¡Oh, gracias por decirme que actualizaré la presentación pronto!
flawr
Vinculaste mi respuesta, pero sí cuento la configuración del lienzo. Simplemente no cuento la línea única que llama a la función. Buenas imágenes de todos modos, espacialmente la primera.
edc65
Ah, no me di cuenta de eso, solo quería hacerlo 'comparable', pero es difícil cuando intento confiar solo en JS =) @ MartinBüttner Actualizado, ahora que lo entendí de la manera correcta pude eliminar gran parte de la basura =)
flawr
3

Procesamiento, 153

Porté la respuesta Java de @Geobits a Processing e hicimos un poco más de golf, lo que resultó en una reducción de 100 caracteres. Originalmente tenía la intención de animar el proceso, pero las restricciones de entrada son demasiado duras en esto (Processing no tiene stdin o argv, lo que significa que debo escribir mi propia función en lugar de usar el draw()ciclo nativo 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]));}

Programa completo con saltos de línea:

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

El programa anterior da cruces: ingrese la descripción de la imagen aquí

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

Esto le da a las pirámides: ingrese la descripción de la imagen aquí

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

Esto le da al triángulo de Sierpinski: ingrese la descripción de la imagen aquí

usuario12205
fuente
44
Me encanta el efecto 3D de las pirámides. :)
Martin Ender
1

"Implementación de referencia" sin golf, Python

Actualizar : mucho, mucho más rápido (por órdenes de magnitud)

¡Mira el shell interactivo!

Edite el archivo y configúrelo interactiveenTrue , a continuación, realice una de las siguientes:

polygon numberOfPoints numeratorOfWeight denominatorOfWeight startX startY numberOfSides genera, guarda y muestra un polígono.

points numberOfPoints numeratorOfWeight denominatorOfWeight startX startY point1X point1Y point2X point2Y ... hace lo que pide la especificación.

ingrese la descripción de la imagen aquí

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
fuente
Sin ejecutar esto, no tengo idea de lo que significa asombroso . ¿Quizás podría explicar o mostrar algunas imágenes de lo que lo hace diferente de las más cortas?
Geobits
@Geobits editado para incluir descargo de responsabilidad y foto :)
Soham Chowdhury
44
Preferiría que incluyera esto bajo un encabezado separado (por ejemplo, Implementación de referencia no protegida) en su otra respuesta, ya que publicar solo código no protegido técnicamente "no es una respuesta".
Martin Ender
-2

Python (202 caracteres)

Toma el número de puntos como n, el peso promedio como r, el punto de partida como ay tuple sla lista de puntos como una lista de XY tuples llamada 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
fuente
@ MartinBüttner ¿El hecho de que estoy tomando un tipo específico de entrada cumple con las especificaciones?
Soham Chowdhury
1
Además, en mi máquina, el resultado no es 600x600 píxeles, xey tienen diferentes escalas de longitud y los puntos cubren más de 1 píxel.
Martin Ender