¡Son factores hasta el final!

23

Este desafío está inspirado en este fantástico diagrama animado (gracias a flawr por publicarlo en el chat).

Dada una entrada n, dibuje todos sus factores primos como polígonos anidados de puntos, como se especifica.

Por ejemplo, dado el número 357 = 17x7x3, usted organiza 3 puntos en un triángulo, 7 versiones de esos triángulos en un heptágono y 17 versiones de esos heptagones en un gon de 17. En resumen, los polígonos anidados van del factor primo más grande en el exterior al más pequeño en el interior. Para 357, su respuesta debería verse un poco así (con o sin color):

ingrese la descripción de la imagen aquí

>= 3No se debe rotar cada polígono de cada primo alrededor del diagrama.

La única excepción es la prima 2, específicamente para poderes extraños de 2. Como puede ver en el ejemplo a 376 = 47x2x2x2continuación, las 8s giran y no son líneas simples de 2s, sino que son pilas verticales para 4s en un cuadrado. Incluso los poderes de 2, dispuestos en cuadrados, no necesitan ser rotados de esta manera.

ingrese la descripción de la imagen aquí

De hecho, 448 = 7x2x2x2x2x2x2tiene un diagrama que se parece a un heptágono de 64s, y 64está organizado en un cuadrado de cuadrados de cuadrados, pero sin rotación.

! [ingrese la descripción de la imagen aquí

Dos ejemplos más son 440 = 11x5x2x2x2y 432 = 3x3x3x2x2x2x2. Vemos que 440con una potencia impar de 2, ha girado 8s, pero 432con una potencia par de 2no gira su 16s.

ingrese la descripción de la imagen aquí ingrese la descripción de la imagen aquí

Y finalmente, aquí hay un ejemplo mínimo 10 = 5x2, sin color del que me burlé con Python y su turtlemódulo.

ingrese la descripción de la imagen aquí

El reto

  • Dada una entrada ndonde 1 <= n <= 10000, genera una imagen de sus polígonos de factor anidado.
  • Las reglas son:
    • La imagen está compuesta de polígonos anidados de puntos, desde un polígono con lados (el factor primo más grande) en el exterior hasta el factor primo más pequeño en el interior.
    • Para el factor 2, las potencias de 2 deben apilarse como una línea, luego un cuadrado, luego una línea de cuadrados, y así sucesivamente. Incluso las potencias de 2 no deben rotarse. Los poderes impares de 2 deben rotarse alrededor de sus respectivos polígonos, y deben apilarse verticalmente antes de la rotación.
  • Puede orientar la imagen como quiera (aunque prefiero hacia arriba), pero cada polígono anidado debe estar orientado en la misma dirección que cualquier otro polígono, con la única excepción de poderes extraños de 2.
  • Tiene dos opciones de tamaño de imagen y tamaño de punto:
    • El tamaño de la imagen es estático y el tamaño del punto disminuye a medida que naumenta (como en la animación).
    • El tamaño del punto es estático y el tamaño de la imagen crece a medida que naumenta.
  • Las primeras tres capas de polígonos deben distinguirse de los polígonos vecinos (es decir, no tocarse), pero teniendo en cuenta el tamaño de las imágenes en y alrededor n=10000, está bien si las capas comienzan a tocarse. Preferiría que no lo hicieran, pero puede ser inevitable encajar en una imagen que se puede cargar en Stack Exchange.
  • El color es opcional.
  • La forma de los puntos depende de usted. Si los cuadrados son mejores para tu idioma, úsalos.
  • Sin bonificaciones, pero me gustaría ver a alguien animar y colorear los diagramas como en la publicación original.

Gracias a Conor O'Brien, EasterlyIrk, Martin Ender, Kritixi Lithos, Mego, DJ McMayhem y El'endia Starman por su ayuda para escribir esta pregunta.

Este código de golf, por lo que gana el código más corto. ¡Buena suerte y buen golf!

Sherlock9
fuente

Respuestas:

8

Python 3.5, 331 309 308 306 304 bytes

Tomó bastante tiempo jugar con el espaciado de los polígonos (y la especificación, también, para ser honesto) para que esta respuesta funcione, pero finalmente lo hice y espero que puedan comenzar a llegar otras respuestas.

Editar: -2 bytes gracias a FlipTack. -8 bytes de eliminar una sección de código que olvidé eliminar antes. -12 bytes de golfing la última función. -1 byte al cambiar la circunferencia de los dibujos de size=2500a size=2e3, lo que también permite que los dibujos se ajusten mejor a las pantallas ( diameter ~= 795.77hasta diameter ~= 636.62). -2 bytes de arreglar un error. -2 bytes de la reestructuración de cómo construyo a.

Sugerencias de golf bienvenidas. Baratija para pruebas e imágenes para seguir en breve.

from math import*
from turtle import*
ht();pu()
def g(n):
 i=1;a=[]
 while n%4<1:a+=4,;n//=4
 while n>1:
  i+=1
  while n%i<1:a+=i,;n//=i
 return f(a,2e3)
def f(a,s,x=0,y=0,t=0):
 if a:
  *c,b=a;s/=b
  for i in range(b):u=2*pi*i/b+t*(b<3)+pi/4*(b==4);f(c,s,x+s*sin(u),y+s*cos(u),u)
 else:goto(x,y);dot(4)

Aquí está g(448), que ahora cabe en mi pantalla de 1366x768.

ingrese la descripción de la imagen aquí

Ungolfing

import math
import turtle

turtle.hideturtle()     # don't display the turtle itself)
turtle.penup()          # don't draw lines, just dots later on

def g(n):
    i = 1
    a = []
    while n % 4 == 0:   # get 4's into the list first,
        a = a + [4]     # so that the fractal will be easier to structure
        n = n // 4
    while n > 1:        # now get all of the other factors (including any stray 2's)
        i += 1
        while n % i == 0:
            a = a + [i]
            n = n // i
    return f(a, 2000)   # 2000 is the circumference of the circle
                        # on which we draw the polygons
def f(a, s, x=0, y=0, t=0):
    if a:
        c = a[-1]       # the size of the current outermost polygon
        b = a[:-1]      # the rest of the factors for recursion
        s = s/b         # the current circumference / the number of polygons at this layer
        for i in range(b):
            u = 2*math.pi*i/b   # angle around the circle
            if b == 2:          # if b == 2, add the previous angle to rotate the structure
                u += t
            if b == 4:          # if b == 4, add 45 degrees to keep the squares upright
                u += math.pi/4
            dx = s * math.sin(u)    # our coordinate changes for this polygon
            dy = s * math.cos(u)
            f(c, s, x+dx, y+dy, u)  # call the function again
                                    # on a new circle with new starting coordinates
    else:                   # when we run out of factors,
        turtle.goto(x,y)    # go to each coordinate
        turtle.dot(4)       # and draw a dot
Sherlock9
fuente
se n = n //= isupone que es n//= i?
Bobas_Pett
@Bobas_Pett Nah, estás viendo la explicación / no golfing, y eso se supone que debe decir n = n // i. Iré a arreglarlo y agregaré a la explicación mientras estoy en ello.
Sherlock9