C'est des facteurs tout le long!

23

Ce défi est inspiré de ce fantastique diagramme animé (merci à flawr de l'avoir posté dans le chat).

Étant donné une entrée n, dessinez tous ses facteurs premiers sous forme de polygones imbriqués de points, comme spécifié.

Par exemple, étant donné le nombre 357 = 17x7x3, vous disposez de 3 points dans un triangle, 7 versions de ces triangles dans un heptagone et 17 versions de ces heptagones dans un 17-gon. Bref, des polygones imbriqués allant du plus grand facteur premier à l'extérieur au plus petit à l'intérieur. Pour 357, votre réponse devrait ressembler un peu à ceci (avec ou sans couleur):

entrez la description de l'image ici

Chaque polygone de chaque nombre premier >= 3ne doit pas tourner autour du diagramme.

La seule exception est la prime 2, en particulier pour les puissances impaires de 2. Comme vous pouvez le voir dans l'exemple 376 = 47x2x2x2ci-dessous, les 8s tournent et ne sont pas des lignes simples de 2s, mais sont des piles verticales pour 4s dans un carré. Même les pouvoirs de 2, disposés en carrés, n'ont pas besoin d'être tournés de cette façon.

entrez la description de l'image ici

En fait, 448 = 7x2x2x2x2x2x2a un diagramme qui ressemble à un heptagone de 64s, et 64est disposé en un carré de carrés de carrés, mais sans rotation.

! [entrez la description de l'image ici

Deux autres exemples sont 440 = 11x5x2x2x2et 432 = 3x3x3x2x2x2x2. On voit 440qu'avec une puissance impaire de 2, a tourné 8s, mais 432avec une puissance paire de 2ne tourne pas ses 16s.

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

Et enfin, voici un exemple minimal 10 = 5x2, sans couleur que j'ai simulé avec Python et son turtlemodule.

entrez la description de l'image ici

Le défi

  • Étant donné une entrée n1 <= n <= 10000, affiche une image de ses polygones de facteurs imbriqués.
  • Les règles sont:
    • L'image est constituée de polygones imbriqués de points, d'un polygone avec (le plus grand facteur premier) côtés à l'extérieur jusqu'au plus petit facteur premier à l'intérieur.
    • Pour le facteur 2, les puissances de 2 doivent s'empiler en ligne, puis en carrés, puis en ligne de carrés, etc. Même les pouvoirs de 2 ne doivent pas être tournés. Les puissances impaires de 2 doivent être tournées autour de leurs polygones respectifs, et elles doivent être empilées verticalement avant la rotation.
  • Vous pouvez orienter l'image comme vous le souhaitez (bien que je préfère vers le haut), mais chaque polygone imbriqué doit être orienté dans la même direction que tout autre polygone à la seule exception des puissances impaires de 2.
  • Vous avez deux options pour la taille de l'image et la taille des points:
    • La taille de l'image est statique et la taille des points diminue à mesure qu'elle naugmente (comme dans l'animation).
    • La taille du point est statique et la taille de l'image augmente à mesure qu'elle naugmente.
  • Les trois premières couches de polygones doivent être distinguées des polygones voisins (c'est-à-dire ne pas se toucher), mais compte tenu de la taille des images à et autour n=10000, ce n'est pas grave si les couches après commencent à se toucher. Je préfèrerais que ce ne soit pas le cas, mais il peut être inévitable de tenir sur une image téléchargeable sur Stack Exchange.
  • La couleur est facultative.
  • La forme des points dépend de vous. Si les carrés conviennent mieux à votre langue, utilisez-les.
  • Pas de bonus, mais j'aimerais voir quelqu'un animer et colorier les diagrammes comme dans le post d'origine.

Merci à Conor O'Brien, EasterlyIrk, Martin Ender, Kritixi Lithos, Mego, DJ McMayhem et El'endia Starman pour leur aide dans la rédaction de cette question.

Ce code golf, donc le code le plus court gagne. Bonne chance et bon golf!

Sherlock9
la source

Réponses:

8

Python 3.5, 331 309 308 306 304 octets

Il a fallu un peu de temps pour jouer avec l'espacement des polygones (et les spécifications aussi, pour être honnête) pour que cette réponse fonctionne, mais je l'ai finalement fait et j'espère que d'autres réponses pourront commencer à arriver.

Edit: -2 octets grâce à FlipTack. -8 octets de suppression d'une section de code que j'ai oublié de supprimer plus tôt. -12 octets de jouer à la dernière fonction. -1 octet pour changer la circonférence des dessins de size=2500à size=2e3, ce qui permet également aux dessins de mieux s'adapter aux écrans ( diameter ~= 795.77jusqu'à diameter ~= 636.62). -2 octets de correction d'un bug. -2 octets de restructuration de la façon dont je construis a.

Suggestions de golf bienvenues. Trinket pour les tests et les images à suivre sous peu.

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)

Voici g(448), qui tient maintenant sur mon écran 1366x768.

entrez la description de l'image ici

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
la source
est n = n //= icensé être n//= i?
Bobas_Pett
@Bobas_Pett Nah, vous regardez le non-golf / explication, et c'est censé dire n = n // i. Je vais le réparer et ajouter à l'explication pendant que j'y suis.
Sherlock9