Уведомления

Группа в Telegram: @pythonsu

#1 Янв. 9, 2018 19:35:14

Comandante4
Зарегистрирован: 2017-12-25
Сообщения: 7
Репутация: +  0  -
Профиль   Отправить e-mail  

Теорема Лагранжа

Согласно теореме Лагранжа любое натуральное число можно представить в виде суммы четырех точных квадратов. По данному числу n найдите такое представление: напечатайте от 1 до 4 натуральных чисел, квадраты которых дают в сумме данное число.
Реализовал задание следующим образом:

 def lagr(n):
    t = []
    for a in range(n, -1, -1):
        for b in range(n, -1, -1):
            for c in range(n, -1, -1):
                for d in range(n, -1, -1):
                    if a ** 2 + b ** 2 + c ** 2 + d ** 2 == n:
                        t = t + [a, b, c, d]
                        s = [x for x in t if x != 0]
                        return s
n = int(input())
print(*lagr(n), end='')
Подскажите, пожалуйста, можно ли это сделать более оптимально? Например, можно ли избежать создания списка для вывода ненулевых значений a, b, c, d? Или, может, можно избежать использование 4-х for?

Офлайн

#2 Янв. 10, 2018 12:13:44

Slow
Зарегистрирован: 2017-07-26
Сообщения: 88
Репутация: +  4  -
Профиль   Отправить e-mail  

Теорема Лагранжа

ну хотя бы от int(sqrt(n)) итерируйтесь, иначе совсем тупо выходит.

а вообще вам нужно найти все разложения или любое?

если все, то вот вам в помощь - https://en.wikipedia.org/wiki/Jacobi%27s_four-square_theorem

Офлайн

#3 Янв. 10, 2018 15:10:03

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9727
Репутация: +  843  -
Профиль   Отправить e-mail  

Теорема Лагранжа

Comandante4
Подскажите, пожалуйста, можно ли это сделать более оптимально?
Надо взять корень числа. Потом от этого корня взять целую часть, возвести её в квадрат и вычесть из числа. Для остатка проделать всё то же самое. Так максимум за четыре шага ты найдёшь все числа.



Офлайн

#4 Янв. 10, 2018 16:12:16

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

Теорема Лагранжа

Comandante4ну начнем с того что вы неправильно интерпретируете теорему.
Теорема Лагранжа утверждает, что любое натуральное число можно представить в виде суммы не более, чем четырех точных квадратов. Пять, например, вы ну никак не представите в виде суммы четырех квадратов, поэтому не стоит зацикливаться на четырех итерациях.

py.user.next
Надо взять корень числа. Потом от этого корня взять целую часть, возвести её в квадрат и вычесть из числа. Для остатка проделать всё то же самое. Так максимум за четыре шага ты найдёшь все числа.
При всей привлекательности такого метода ,как ни странно но нет, хотя очень много чисел удасться разложить подобным методом но, например, 23 по такой методе раскладывается на 5 чисел : 4, 2, 1, 1, 1, а 167 на шесть: 12, 4, 2, 1, 1, 1.
Его нужно доработать



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Отредактировано PEHDOM (Янв. 10, 2018 16:24:23)

Офлайн

#5 Янв. 10, 2018 16:41:36

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9727
Репутация: +  843  -
Профиль   Отправить e-mail  

Теорема Лагранжа

PEHDOM
23 по такой методе раскладывается на 5 чисел
Там нужно тогда (если не уложился в четыре шага) из первого корня вычесть единицу и получившееся значение использовать как будто это и был корень. И это происходит тоже на каждом шаге, то есть не только для первого корня. Тут нужна рекурсивная функция, которая принимает число и максимальное количество шагов для его разложения. И так на каждом шаге при взятии корня эта функция вызывается с уменьшенным максимальным количеством шагов на единицу. Ну числа могут быть большими, поэтому надо на всех уровнях раскладывать оптимально.



Офлайн

#6 Янв. 10, 2018 20:19:47

Slow
Зарегистрирован: 2017-07-26
Сообщения: 88
Репутация: +  4  -
Профиль   Отправить e-mail  

Теорема Лагранжа

PEHDOM
Comandante4ну начнем с того что вы неправильно интерпретируете теорему.Теорема Лагранжа утверждает, что любое натуральное число можно представить в виде суммы не более, чем четырех точных квадратов. Пять, например, вы ну никак не представите в виде суммы четырех квадратов, поэтому не стоит зацикливаться на четырех итерациях.

Нули вообще то тоже можно.
5 = 2**2 + 1**2 + 0**2 + 0**2

Офлайн

#7 Янв. 16, 2018 22:30:33

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

Теорема Лагранжа

Comandante4 Ну вобщем py.user.next все верно написал, наиболее оптимально будет рекурсивная функция, которая принимает число и максимальное количество шагов для его разложения.
Если вам интерсно самому сделать, пробуйте. Сразу скажу готовое решение есть(и не одно), но пока не буду его приводить, вдруг вы хотите сами разобраться.

Теперь замечания по поводу именно вашего алгоритма.
1. нет смысла делать четыре цикла по n, максимально возможный корень будет int(n**0.5), следовательно перебирать варианты более этого значения бессмыслено. Вы получите существенный прирост в скорости даже не в разы, а на порядки.
2. вы делаете a ** 2 + b ** 2 + c ** 2 + d ** 2 каждый раз в самом вложеном цикле, хотя достаточно делать вычислять квадрат a,b,c и d соотвевенно только при их изменении, что еще добавит скорости
3. поскольку мы возводим только в квадрат, то заменить a ** 2 на а*а, это еще чутка добавит производительности, (это уже особенности алгоритма возведения в степень пайтоном).



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Отредактировано PEHDOM (Янв. 16, 2018 22:32:48)

Офлайн

#8 Янв. 8, 2020 17:16:33

vanyamoscow
Зарегистрирован: 2020-01-08
Сообщения: 1
Репутация: +  0  -
Профиль   Адрес электронной почты  

Теорема Лагранжа

PEHDOM

PEHDOM
Сразу скажу готовое решение есть(и не одно), но пока не буду его приводить, вдруг вы хотите сами разобраться.

Добрый вечер! А не могли бы вы мне решение в виде рекурсивной функции в личку скинуть. Спасибо!

Офлайн

#9 Апрель 16, 2020 18:44:24

al_orange
Зарегистрирован: 2020-04-16
Сообщения: 4
Репутация: +  0  -
Профиль   Отправить e-mail  

Теорема Лагранжа

PEHDOM, пожалуйста, проверцте личку

vanyamoscow, пожалуйста, поделитесь решением, если раздобыли, а пока не справилась с этой задачкой

Офлайн

#10 Апрель 17, 2020 10:39:19

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9727
Репутация: +  843  -
Профиль   Отправить e-mail  

Теорема Лагранжа

Оптимизировал без рекурсии. Сделал юнит-тесты.

Идея с последовательным вычислением корней не сработала.



Отредактировано py.user.next (Апрель 17, 2020 10:42:01)

Прикреплённый файлы:
attachment lagrsq.tar.gz (1,1 KБ)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version