Это факторы вниз!

23

Эта задача вдохновлена этой фантастической анимированной диаграммой (спасибо flawr за публикацию в чате).

Получив входные данные n, нарисуйте все его простые факторы в виде вложенных полигонов точек, как указано.

Например, учитывая число 357 = 17x7x3, вы размещаете 3 точки в треугольнике, 7 версий этих треугольников в семиугольнике и 17 версий этих семиугольников в 17-угольном. Короче говоря, вложенные многоугольники идут от наибольшего простого фактора снаружи к наименьшему внутри. Для 357, ваш ответ должен выглядеть немного , как это (с или без цвета):

введите описание изображения здесь

Каждый многоугольник каждого простого числа >= 3не должен вращаться вокруг диаграммы.

Единственным исключением является простое число 2, особенно для нечетных степеней 2. Как вы можете видеть в приведенном 376 = 47x2x2x2ниже примере , 8s вращаются и представляют собой не одну строку 2s, а вертикальные стеки для 4s в квадрате. Даже силы 2, расположенные в квадратах, не нужно вращать таким образом.

введите описание изображения здесь

На самом деле, 448 = 7x2x2x2x2x2x2имеет диаграмму, которая выглядит как семиугольник 64s, и 64организована в квадрат квадратов квадратов, но без вращения.

! [введите описание изображения здесь

Еще два примера есть 440 = 11x5x2x2x2и 432 = 3x3x3x2x2x2x2. Мы видим, что 440с нечетной степенью 2 повернул 8s, но 432с четной степенью 2не повернул 16s.

введите описание изображения здесь введите описание изображения здесь

И, наконец, вот минимальный пример, 10 = 5x2без цвета, который я смоделировал с Python и его turtleмодулем.

введите описание изображения здесь

Соревнование

  • Учитывая вход, nгде 1 <= n <= 10000, выведите изображение его вложенных фактор-полигонов.
  • Правила таковы:
    • Изображение состоит из вложенных многоугольников точек, от многоугольника с (наибольшим основным фактором) сторон снаружи до наименьшего простого множителя внутри.
    • Для множителя 2 степени 2 должны складываться как линия, затем квадраты, затем линия квадратов и так далее. Даже степени 2 не должны вращаться. Нечетные степени 2 должны вращаться вокруг их соответствующих многоугольников, и они должны быть сложены вертикально перед вращением.
  • Вы можете ориентировать изображение так, как вам нравится (хотя я предпочитаю вверх), но каждый вложенный многоугольник должен быть направлен в том же направлении, что и любой другой многоугольник, за исключением нечетных степеней 2.
  • У вас есть два варианта размера изображения и размера точки:
    • Размер изображения статичен, а размер точек уменьшается по мере nувеличения (как в анимации).
    • Размер точки является статическим, а размер изображения увеличивается по мере nувеличения.
  • Первые три слоя многоугольников должны отличаться от соседних многоугольников (то есть не касаться), но, учитывая размер изображений вокруг и вокруг n=10000, все в порядке, если слои после начинают касаться. Я бы предпочел, если бы они этого не сделали, но это может быть неизбежно вписано в изображение, которое можно загрузить в Stack Exchange.
  • Цвет не является обязательным.
  • Форма точек зависит от вас. Если квадраты лучше для вашего языка, используйте их.
  • Никаких бонусов, но я бы хотел, чтобы кто-то оживил и раскрасил диаграммы, как в оригинальном посте.

Спасибо Конору О'Брайену, ИстерлиИрку, Мартину Эндеру, Критиси Литосу, Мего, DJ McMayhem и El'endia Starman за помощь в написании этого вопроса.

Это код гольф, поэтому самый короткий код выигрывает. Удачи и хорошего гольфа!

Sherlock9
источник

Ответы:

8

Python 3.5, 331 309 308 306 304 байта

Чтобы получить этот ответ, потребовалось немало возиться с расстоянием между полигонами (и, если честно, со спецификацией), но я наконец сделал это, и, надеюсь, другие ответы могут начать поступать.

Редактировать: -2 байта благодаря FlipTack. -8 байт от удаления раздела кода, который я забыл удалить ранее. -12 байт от игры в гольф последней функции. -1 байт от изменения длины окружности чертежей с size=2500до size=2e3, что также позволяет чертежам лучше помещаться на экранах ( diameter ~= 795.77вплоть до diameter ~= 636.62). -2 байта от исправления ошибки. -2 байта от реструктуризации, как я строюa .

Предложения по игре в гольф приветствуются. Брелок для тестирования и изображения, чтобы следовать в ближайшее время.

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)

Вот g(448), что сейчас умещается на моем экране 1366x768.

введите описание изображения здесь

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
источник
это n = n //= iдолжно быть n//= i?
Bobas_Pett
@Bobas_Pett Нет, ты смотришь на разгул / объяснение, и это должно сказать n = n // i. Я пойду исправлю это и добавлю к объяснению, пока я на нем.
Sherlock9