São fatores por todo o caminho!


23

Este desafio é inspirado neste fantástico diagrama animado (obrigado à flawr por publicá-lo no chat).

Dada uma entrada n, desenhe todos os seus fatores primos como polígonos aninhados de pontos, conforme especificado.

Por exemplo, dado o número 357 = 17x7x3, você organiza 3 pontos em um triângulo, 7 versões desses triângulos em um heptágono e 17 versões desses heptágonos em 17 gon. Em resumo, polígonos aninhados que vão do maior fator primo do lado de fora ao menor do lado de dentro. Pois 357, sua resposta deve se parecer um pouco com isso (com ou sem cor):

insira a descrição da imagem aqui

Todos os polígonos de todos os primos >= 3não devem ser rotacionados em torno do diagrama.

A única exceção é a principal 2, especificamente para poderes ímpares de 2. Como você pode ver no exemplo 376 = 47x2x2x2abaixo, os 8s giram e não são linhas únicas de 2s, mas são pilhas verticais de 4s em um quadrado. Mesmo os poderes de 2, dispostos em quadrados, não precisam ser rotacionados dessa maneira.

insira a descrição da imagem aqui

De fato, 448 = 7x2x2x2x2x2x2possui um diagrama que se parece com um heptágono de 64s e 64é organizado em um quadrado de quadrados de quadrados, mas sem rotação.

! [insira a descrição da imagem aqui

Mais dois exemplos são 440 = 11x5x2x2x2e 432 = 3x3x3x2x2x2x2. Vemos que, 440com uma potência ímpar de 2, girou 8s, mas 432com uma potência par de 2não gira seus 16s.

insira a descrição da imagem aqui insira a descrição da imagem aqui

E, finalmente, aqui está um exemplo mínimo 10 = 5x2, sem cores que eu zombei do Python e de seu turtlemódulo.

insira a descrição da imagem aqui

O desafio

  • Dada uma entrada em nque 1 <= n <= 10000, produz uma imagem de seus polígonos de fator aninhados.
  • As regras são:
    • A imagem é composta de polígonos aninhados de pontos, de um polígono com (o maior fator primo) lados do lado de fora até o menor fator primo do lado de dentro.
    • Para o fator 2, as potências de 2 devem ser empilhadas como uma linha, depois um quadrado, depois uma linha de quadrados e assim por diante. Mesmo potências de 2 não devem ser giradas. Poderes ímpares de 2 devem ser rotacionados em torno de seus respectivos polígonos e devem ser empilhados verticalmente antes da rotação.
  • Você pode orientar a imagem da maneira que desejar (embora eu prefira), mas todo polígono aninhado deve estar voltado para a mesma direção que qualquer outro polígono, com a única exceção dos poderes ímpares de 2.
  • Você tem duas opções para tamanho da imagem e tamanho do ponto:
    • O tamanho da imagem é estático e o tamanho do ponto diminui à medida que naumenta (como na animação).
    • O tamanho do ponto é estático e o tamanho da imagem aumenta à medida que naumenta.
  • As três primeiras camadas de polígonos devem ser distinguíveis dos polígonos vizinhos (ou seja, sem tocar), mas, considerando o tamanho das imagens em torno e ao redor n=10000, não há problema se as camadas depois começarem a tocar. Eu preferiria que não, mas pode ser inevitável caber em uma imagem que pode ser carregada no Stack Exchange.
  • A cor é opcional.
  • A forma dos pontos depende de você. Se os quadrados são melhores para o seu idioma, use-os.
  • Sem bônus, mas eu gostaria de ver alguém animar e colorir os diagramas como no post original.

Agradecimentos a Conor O'Brien, EasterlyIrk, Martin Ender, Kritixi Lithos, Mego, DJ McMayhem e El'endia Starman por sua ajuda na redação desta pergunta.

Esse código de golfe, então o código mais curto vence. Boa sorte e bom golfe!

Respostas:


8

Python 3.5, 331 309 308 306 304 bytes

Demorou um pouco para mexer com o espaçamento dos polígonos (e também com as especificações, para ser honesto) para que essa resposta funcionasse, mas finalmente fiz isso e espero que outras respostas possam começar a aparecer.

Edit: -2 bytes graças ao FlipTack. -8 bytes de remoção de uma seção de código que eu esqueci de remover anteriormente. -12 bytes de golfe na última função. -1 byte de alterar a circunferência dos desenhos de size=2500para size=2e3, o que também permite que os desenhos se ajustem melhor às telas ( diameter ~= 795.77abaixo diameter ~= 636.62). -2 bytes de correção de um bug. -2 bytes de reestruturação como eu construo a.

Sugestões de golfe são bem-vindas. Trinket para testes e imagens a seguir em 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)

Aqui está g(448), que agora cabe na minha tela de 1366x768.

insira a descrição da imagem aqui

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

é n = n //= isuposto ser n//= i?
21816 Bobbid_Pett

@Bobas_Pett Nah, você está olhando para o descrédito / explicação, e isso deveria dizer n = n // i. Vou corrigi-lo e adicionar à explicação enquanto estou nisso.
Sherlock9
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.