Sono fattori fino in fondo!


23

Questa sfida è ispirata a questo fantastico diagramma animato (grazie a Flawr per averlo pubblicato in chat).

Dato un input n, disegna tutti i suoi fattori primi come poligoni nidificati di punti, come specificato.

Ad esempio, dato il numero 357 = 17x7x3, disponi 3 punti in un triangolo, 7 versioni di quei triangoli in un ettagono e 17 versioni di quegli eptagoni in un 17 gon. In breve, i poligoni nidificati vanno dal più grande fattore primo all'esterno al più piccolo all'interno. Perché 357, la tua risposta dovrebbe apparire un po 'così (con o senza colore):

inserisci qui la descrizione dell'immagine

Ogni poligono di ogni numero primo >= 3non deve essere ruotato attorno al diagramma.

L'unica eccezione è il primo 2, in particolare per i poteri dispari di 2. Come puoi vedere nell'esempio che 376 = 47x2x2x2segue, le 8s ruotano e non sono singole linee di 2s, ma sono pile verticali per 4s in un quadrato. Anche i poteri di 2, disposti in quadrati, non devono essere ruotati in questo modo.

inserisci qui la descrizione dell'immagine

In effetti, 448 = 7x2x2x2x2x2x2ha un diagramma che assomiglia a un ettagono di 64s, ed 64è organizzato in un quadrato di quadrati di quadrati, ma senza rotazione.

! [inserisci la descrizione dell'immagine qui

Altri due esempi sono 440 = 11x5x2x2x2e 432 = 3x3x3x2x2x2x2. Vediamo che 440con una potenza dispari di 2, ha ruotato 8s, ma 432con una potenza pari a 2non ruota i suoi 16s.

inserisci qui la descrizione dell'immagine inserisci qui la descrizione dell'immagine

E infine, ecco un esempio minimo 10 = 5x2, senza colore che ho preso in giro con Python e il suo turtlemodulo.

inserisci qui la descrizione dell'immagine

La sfida

  • Dato un input in ncui 1 <= n <= 10000, output un'immagine dei suoi poligoni fattore nidificato.
  • Le regole sono:
    • L'immagine è composta da poligoni nidificati di punti, da un poligono con (il più grande fattore primo) lati all'esterno al più piccolo fattore primo all'interno.
    • Per il fattore 2, i poteri di 2 dovrebbero impilarsi come una linea, quindi un quadrato, quindi una linea di quadrati e così via. Anche i poteri di 2 non devono essere ruotati. Poteri dispari di 2 dovrebbero essere ruotati attorno ai rispettivi poligoni e dovrebbero essere impilati verticalmente prima della rotazione.
  • Puoi orientare l'immagine come preferisci (anche se preferisco), ma ogni poligono nidificato dovrebbe essere rivolto nella stessa direzione di qualsiasi altro poligono, con la sola eccezione dei poteri dispari di 2.
  • Sono disponibili due opzioni per la dimensione dell'immagine e la dimensione del punto:
    • La dimensione dell'immagine è statica e la dimensione del punto diminuisce nall'aumentare (come nell'animazione).
    • La dimensione del punto è statica e la dimensione dell'immagine aumenta nall'aumentare.
  • I primi tre strati di poligoni dovrebbero essere distinguibili dai poligoni vicini (cioè non toccanti), ma considerando la dimensione delle immagini intorno e intorno n=10000, va bene se gli strati dopo iniziano a toccarsi. Preferirei se non lo facessero, ma potrebbe essere inevitabile adattarsi a un'immagine caricabile su Stack Exchange.
  • Il colore è facoltativo
  • La forma dei punti dipende da te. Se i quadrati sono migliori per la tua lingua, usa quelli.
  • Nessun bonus, ma vorrei vedere qualcuno animare e colorare i diagrammi come nel post originale.

Grazie a Conor O'Brien, EasterlyIrk, Martin Ender, Kritixi Lithos, Mego, DJ McMayhem e El'endia Starman per il loro aiuto nello scrivere questa domanda.

Questo codice golf, quindi il codice più corto vince. Buona fortuna e buon golf!

Risposte:


8

Python 3.5, 331 309 308 306 304 byte

Ci è voluto un po 'di confusione con la spaziatura dei poligoni (e anche le specifiche, a dire il vero) per far funzionare questa risposta, ma alla fine l'ho fatto e spero che possano iniziare ad arrivare altre risposte.

Modifica: -2 byte grazie a FlipTack. -8 byte dalla rimozione di una sezione di codice che ho dimenticato di rimuovere in precedenza. -12 byte dal golf l'ultima funzione. -1 byte dalla modifica della circonferenza dei disegni da size=2500a size=2e3, che consente anche ai disegni di adattarsi meglio agli schermi ( diameter ~= 795.77fino a diameter ~= 636.62). -2 byte dalla correzione di un bug. -2 byte dalla ristrutturazione di come costruisco a.

Suggerimenti di golf benvenuti. Trinket per test e immagini che seguiranno a 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)

Ecco g(448), che ora si adatta al mio schermo 1366x768.

inserisci qui la descrizione dell'immagine

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

si n = n //= idovrebbe essere n//= i?
Bobas_Pett,

@Bobas_Pett Nah, stai guardando la nongolfing / spiegazione, e questo dovrebbe dirlo n = n // i. Vado a sistemarlo e aggiungerò alla spiegazione mentre ci sono.
Sherlock9,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.