Минимумитерации рисования правильной формы («черепаха») - PullRequest
0 голосов
/ 03 февраля 2019

Я пытаюсь найти наименьшее количество итераций, необходимое для формирования правильного многоугольника, чтобы моя "черепаха" (фигура) не повторяла его движение ... и заметил странное (?) Отношение, которое я не могу точно определить.

Если вы запустите приведенный ниже код и поэкспериментируете с другими значениями (ПРИМЕЧАНИЕ: обязательно замените параметры 'x' & 'n' фактическими числами - по вашему выбору):

import turtle

def draw_square():
    wn = turtle.Screen()
    wn.bgcolor("black")
    mike = turtle.Turtle()
    mike.shape("turtle")
    mike.color("yellow")
    mike.speed(100)

    count = 0
    while count < n:                    # replace n with number!
        mike.forward(100)
        mike.right(90)
        mike.forward(100)
        mike.right(90)
        mike.forward(100)
        mike.right(90)
        mike.forward(100)
        mike.right(x)                   # replace x with number!

if __name__ == "__main__":
    draw_square()

Вы будетенайдите черепаху, которая движется круговыми (-ишами) движениями.

Например, вы заметите, что когда x = 100, мин.значение n, необходимое для формирования правильной формы, равно 36 (поскольку 100 ° - 90 ° = 10 °; 360 ° / 10 ° = 36). при x = 10, например .

Дальнейшие тесты показывают:

x = 1, (min.) n = 360                   # 360°/1° = 360

x = 5, (min.) n = 72                    # 360°/5° = 72

x = 9, (min.) n = 10*                   # 360°/9° = 10*

x = 10, (min.) n = 9*                   # 360°/10° = 9*

x = 45, (min.) n = 8                    # 360°/45° = 8

x = 90, (min.) n = 1*                   # 360°/90° = 4*

## NOTE: no obvs. solution for n, if x isn't factor of 360....

*: странно, вы должны разделить результат на 4, чтобы получить мин.значение n для некоторых чисел.Сначала я думал, что это связано с кратностью 9 или четырьмя поворотами для квадрата, но [выше] побудило меня отказаться от моих гипотез.

Таким образом, у кого-нибудь есть лучшие идеи относительно общего правила?Приветствия.

Ответы [ 2 ]

0 голосов
/ 05 февраля 2019

Далее из набора правил, идентифицированного @cdlane, я нашел быстрый способ найти только мин.количество итераций для любого ввода x - независимо от того, является ли он фактором 360 или нет - необходимое для завершения правильной формы!(Конечно, я также понял, что для некоторых не будет минимального значения, например, когда x равен 20,75)

.

Ниже код показывает мои исправления к выявленным неисправностям и добавлениюheading (), чтобы проверить, вернулся ли Майк в исходное положение после цикла (ов):

import turtle

def draw_square(angle, repetitions):
    mike = turtle.Turtle()
    mike.shape("turtle")
    mike.color("red")
    mike.speed("fastest")

    count = 0
    while count < repetitions:
        mike.forward(100)
        mike.right(90)
        mike.forward(100)
        mike.right(90)
        mike.forward(100)
        mike.right(90)
        mike.forward(100)
        mike.right(angle)

        count += 1

        print("Turn ", count, "; ", mike.heading())

        if mike.heading() == 0:
            break

    print("Min. iterations needed to complete cycle:  ", count)

if __name__ == "__main__":
    wn = turtle.Screen()
    wn.bgcolor("black")

    x = int(input("Enter angle: "))
    n = int(input("Enter boundary: "))        # For n, advisably to a v large number; while loop will probably break before reaching its limit anyways

    draw_square(x, n)
    wn.exitonclick()
0 голосов
/ 03 февраля 2019

Значит, у кого-нибудь есть идеи по поводу общего правила?

Мне кажется, я его сузил.В вашей таблице есть некоторые ошибки.И есть четыре различных типа исключений, а не просто «разделить результат на 4».Фактически, среди факторов 360, исключения встречаются чаще, чем простое правило 360 / x.Четырьмя исключениями являются:

После, n = 360 / x, если x является:

A) multiple of 8 then n *= 4
B) multiple of 4 then n *= 2
C) multiple of 6 and not a multiple of 9 then n /= 2
D) multiple of 2 then n /= 4

Правила должны применяться в указанном выше порядке, и может выполняться только одно правило.Если правила не применяются, оставьте n без изменений.Пересмотренная таблица для всех факторов 360:

x =   1, n = 360      , 360° /   1° = 360 
x =   2, n =  45 (/ 4), 360° /   2° = 180 (D)
x =   3, n = 120      , 360° /   3° = 120 
x =   4, n = 180 (* 2), 360° /   4° =  90 (B)
x =   5, n =  72      , 360° /   5° =  72 
x =   6, n =  30 (/ 2), 360° /   6° =  60 (C)
x =   8, n = 180 (* 4), 360° /   8° =  45 (A)
x =   9, n =  40      , 360° /   9° =  40 
x =  10, n =   9 (/ 4), 360° /  10° =  36 (D)
x =  12, n =  60 (* 2), 360° /  12° =  30 (B)
x =  15, n =  24      , 360° /  15° =  24 
x =  18, n =   5 (/ 4), 360° /  18° =  20 (D)
x =  20, n =  36 (* 2), 360° /  20° =  18 (B)
x =  24, n =  60 (* 4), 360° /  24° =  15 (A)
x =  30, n =   6 (/ 2), 360° /  30° =  12 (C)
x =  36, n =  20 (* 2), 360° /  36° =  10 (B)
x =  40, n =  36 (* 4), 360° /  40° =   9 (A)
x =  45, n =   8      , 360° /  45° =   8 
x =  60, n =  12 (* 2), 360° /  60° =   6 (B)
x =  72, n =  20 (* 4), 360° /  72° =   5 (A)
x =  90, n =   1 (/ 4), 360° /  90° =   4 (D)
x = 120, n =  12 (* 4), 360° / 120° =   3 (A)
x = 180, n =   4 (* 2), 360° / 180° =   2 (B)
x = 360, n =   4 (* 4), 360° / 360° =   1 (A)

Код, сгенерировавший приведенную выше таблицу:

EXCEPTIONS = [
    ('A', lambda x: x % 8 == 0, lambda n: n * 4, "(* 4)"),
    ('B', lambda x: x % 4 == 0, lambda n: n * 2, "(* 2)"),
    ('C', lambda x: x % 6 == 0 and x % 9 != 0, lambda n: n // 2, "(/ 2)"),
    ('D', lambda x: x % 2 == 0, lambda n: n // 4, "(/ 4)"),
]

for x in range(1, 360 + 1):
    if 360 % x != 0:
        continue

    n = 360 // x

    for exception, test, outcome, explain in EXCEPTIONS:
        if test(x):
            n = outcome(n)
            exception = f"({exception})"
            break
    else:  # no break
        exception = explain = ''  # no rule applies

    angle = 360 // x

    print(f"x = {x:3}, n = {n:3} {explain:5}, 360° / {x:3}° = {angle:3} {exception}")

Моя переделка вашего кода, которую я использовал для проверки отдельных записей таблицы:

from turtle import Screen, Turtle

def draw_square(angle, repetitions):
    mike = Turtle("turtle")
    mike.speed('fastest')
    mike.color("yellow")

    count = 0

    while count < repetitions:
        mike.forward(100)
        mike.right(90)
        mike.forward(100)
        mike.right(90)
        mike.forward(100)
        mike.right(90)
        mike.forward(100)
        mike.right(angle)

        count += 1

if __name__ == "__main__":
    wn = Screen()
    wn.bgcolor("black")

    draw_square(9, 40)

    wn.exitonclick()

enter image description here

...