Es ist Faktoren den ganzen Weg nach unten!

23

Diese Herausforderung ist von diesem fantastischen animierten Diagramm inspiriert (danke an flawr für die Veröffentlichung im Chat).

nZeichnen Sie bei einer Eingabe alle Primfaktoren wie angegeben als verschachtelte Punktpolygone.

Angenommen 357 = 17x7x3, Sie ordnen 3 Punkte in einem Dreieck, 7 Versionen dieser Dreiecke in einem Siebeneck und 17 Versionen dieser Siebenecke in einem Siebeneck an. Kurz gesagt, verschachtelte Polygone vom größten Primfaktor außen zum kleinsten im Inneren. Für 357Ihre Antwort ein wenig so aussehen sollte (mit oder ohne Farbe):

Bildbeschreibung hier eingeben

Jedes Polygon eines jeden Strichs >= 3sollte nicht um das Diagramm gedreht werden.

Die einzige Ausnahme ist die Primzahl 2, speziell für ungerade Potenzen von 2. Wie Sie im folgenden Beispiel sehen können 376 = 47x2x2x2, 8drehen sich die s und sind keine einzelnen Zeilen von 2s, sondern vertikale Stapel für 4s in einem Quadrat. Auch Potenzen von 2, in Quadraten angeordnet, müssen auf diese Weise nicht gedreht werden.

Bildbeschreibung hier eingeben

In der Tat 448 = 7x2x2x2x2x2x2hat ein Diagramm, das wie ein Siebeneck von 64s aussieht , und 64ist in ein Quadrat von Quadraten von Quadraten angeordnet, aber ohne Drehung.

! [Bildbeschreibung hier eingeben

Zwei weitere Beispiele sind 440 = 11x5x2x2x2und 432 = 3x3x3x2x2x2x2. Wir sehen, dass 440mit einer ungeraden Potenz von 2 8s gedreht hat , aber 432mit einer geraden Potenz von 2nicht seine 16s dreht .

Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben

Und schließlich ist hier ein minimales Beispiel 10 = 5x2ohne Farbe, das ich mit Python und seinem turtleModul nachgebildet habe.

Bildbeschreibung hier eingeben

Die Herausforderung

  • Ein Eingang gegeben , nwo der 1 <= n <= 10000Ausgang ein Bild von seinem verschachtelten Faktor Polygonen.
  • Regeln sind:
    • Das Bild besteht aus verschachtelten Punktpolygonen, von einem Polygon mit (dem größten Primfaktor) Seiten an der Außenseite bis zum kleinsten Primfaktor an der Innenseite.
    • Für den Faktor 2 sollten die Potenzen von 2 als Linie, dann als Quadrate, dann als Quadratlinie usw. gestapelt werden. Selbst Zweierpotenzen sollten nicht gedreht werden. Ungerade Potenzen von 2 sollten um ihre jeweiligen Polygone gedreht und vor der Drehung vertikal gestapelt werden.
  • Sie können das Bild so ausrichten, wie Sie es möchten (ich bevorzuge es nach oben), aber jedes verschachtelte Polygon sollte in dieselbe Richtung weisen wie jedes andere Polygon, mit Ausnahme von ungeraden Potenzen von 2.
  • Sie haben zwei Optionen für die Bildgröße und die Punktgröße:
    • Die Bildgröße ist statisch und die Punktgröße nimmt mit nzunehmender Größe ab (wie in der Animation).
    • Die Punktgröße ist statisch und die Bildgröße wächst mit nzunehmender Größe .
  • Die ersten drei Ebenen von Polygonen sollten von benachbarten Polygonen unterscheidbar sein (dh sie berühren sich nicht). Angesichts der Größe der Bilder in und um n=10000diese herum ist es jedoch in Ordnung, wenn die Ebenen nach dem Berühren beginnen. Ich würde es vorziehen, wenn dies nicht der Fall wäre, aber es könnte unvermeidlich sein, auf ein Image zu passen, das auf Stack Exchange hochgeladen werden kann.
  • Farbe ist optional.
  • Die Form der Punkte liegt bei Ihnen. Wenn Quadrate für Ihre Sprache besser sind, verwenden Sie diese.
  • Keine Boni, aber ich möchte jemanden animieren und die Diagramme wie im ursprünglichen Beitrag ausmalen sehen.

Wir danken Conor O'Brien, EasterlyIrk, Martin Ender, Kritixi Lithos, Mego, DJ McMayhem und El'endia Starman für ihre Hilfe beim Schreiben dieser Frage.

Dieser Code Golf, so dass der kürzeste Code gewinnt. Viel Glück und gutes Golfen!

Sherlock9
quelle

Antworten:

8

Python 3.5, 331 309 308 306 304 Bytes

Es hat einiges an Mühe gekostet, den Abstand der Polygone (und, um ehrlich zu sein, auch die Spezifikation) zu ändern, damit diese Antwort funktioniert, aber ich habe es endlich geschafft, und hoffentlich können andere Antworten eingehen.

Edit: -2 Bytes dank FlipTack. -8 Bytes vom Entfernen eines Codeabschnitts, den ich zuvor vergessen habe, zu entfernen. -12 Bytes vom Golfen der letzten Funktion. -1 Byte vom Ändern des Zeichnungsumfangs von size=2500nach size=2e3, wodurch die Zeichnungen auch besser auf Bildschirme passen (diameter ~= 795.77 bis zu diameter ~= 636.62) . -2 Bytes vom Beheben eines Fehlers. -2 Bytes von der Umstrukturierung, wie ich baue a.

Golfen Vorschläge willkommen. Trinket zum Testen und Bilder folgen in Kürze.

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)

Hier ist g(448), was jetzt auf meinen 1366x768 Bildschirm passt.

Bildbeschreibung hier eingeben

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
quelle
wird n = n //= isein soll n//= i?
Bobas_Pett
@Bobas_Pett Nee, du schaust auf die Ungolfing / Erklärung und das soll heißen n = n // i. Ich werde das Problem beheben und die Erklärung ergänzen, während ich dabei bin.
Sherlock9