Форум программистов, компьютерный форум, киберфорум
Python для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.63/103: Рейтинг темы: голосов - 103, средняя оценка - 4.63
Эксперт Python
8851 / 4502 / 1864
Регистрация: 27.03.2020
Сообщений: 7,320

Разложение на множители

19.08.2020, 09:43. Показов 20270. Ответов 31
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Задача разложения числа на простые(!) множители решается многими методами и довольно быстро.
Существует ли встроенная функция или метод для волучения всех(!) вариантов получения числа произведением других натуральных чисел.
Для себя сделал, но, например, для числа 720 время нахождения всех вариантов занимает ~ 0,3 сек
Хотелось бы быстрее
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
19.08.2020, 09:43
Ответы с готовыми решениями:

Разложение на множители
Добрый день. Нужно разложить число на множители в виде: 24=2*2*2*2*3. Но в программе получается результат: 24=2*2*2*3. Не знаю, откуда...

Разложение на простые множители
Требуется разложить целое число N на простые множители и вывести результат в порядке возрастания множителей с указанием степени. ...

Разложение на простые множители
Разложение на простые множители Требуется разложить целое число N на простые множители с учётом их степени и вывести результат в порядке...

31
Эксперт Python
8851 / 4502 / 1864
Регистрация: 27.03.2020
Сообщений: 7,320
19.08.2020, 16:26  [ТС]
Студворк — интернет-сервис помощи студентам
ФедосеевПавел,
Не всегда
У 24 максимально длинное - 2, 2, 2, 3
А "верным" разложением будет - 2, 3, 4
0
Status 418
Эксперт Python
4584 / 2350 / 601
Регистрация: 26.11.2017
Сообщений: 5,262
Записей в блоге: 3
19.08.2020, 18:22
для N = 997
ответ:
6696928794914170755927656556625011316008 7800731595850465234399273146940695308507 6558248986759809911329746670573470716765 7419658035576962772490360984186609252459 1048592651443658881716281639819636737213 6384565404686473871329212422972447846496 6298164321606997798554088854787768644782 89024177325354254336

что равно
Кликните здесь для просмотра всего текста
2**996


Добавлено через 4 минуты
для N = 996
996 = 2 * 2 * 3 * 83

ответ:
1523246532714432760129781760
что равно
Кликните здесь для просмотра всего текста
(2** 82) * (3**2) * (5**1) * (7**1)


или я не прав?
0
Эксперт Python
8851 / 4502 / 1864
Регистрация: 27.03.2020
Сообщений: 7,320
19.08.2020, 19:01  [ТС]
Прав
Оба ответа верны

Добавлено через 11 минут
Полный код :
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
def delit(a) :
    res = []
    i = 1
    while i * i < a + 1 :
        if a % i == 0 :
            temp = [i, a // i]
            res.append(temp)
        i += 1
    return res 
    
n = int(input())
npr = [2,3,5,7,11,13,17,19,23,29]
 
# первичное разложение на парные делители
fact = delit(n)
 
flen = len(fact)
while True :
    for j in range(flen) :
        zero = 1
 
        # если в очередном списке делителей 
        #есть "1", пропустить
        if 1 not in fact[j] :
            zero = 0
            n1 = list(fact[j])
 
            # "вытаскиваем" последний делитель из списка
            # и ищем все попарные разложения на множители
            factj = delit(n1.pop())
 
            # каждую полученную пару 
            #объединяем со списком
            for k in range(len(factj)) :
                factj[k].extend(n1)
                factj[k].sort()
                fact.append(factj[k])
    flen = len(fact)
 
    # если zero не изменилось во всех списках,
    # все варианты найдены
    if zero == 1:
        break
 
# удаляем 1 из всех вариантов
for ik in fact :
    ik.sort(reverse=True)
    if ik[-1] == 1 :
        ik.pop()
 
# удаляем одинаковые списки
fact.sort()
print(len(fact))
j =[0]
resj = []
for i in fact :
    if i != j :
        resj.append(i)
    j=i
print(len(resj))
######################################
 
minc = int(1e300) + 1
for i in resj :
    j = 0
    ss = 1
    for ii in i:
        ss *= npr[j] ** (ii-1)
        if ss > int(1e300) + 1 :
            ss = int(1e300) + 1
            break
        j += 1
    minc = min(minc,ss)
print(minc)
Проблема в том, что цикл "while True" создает, например, для 720 29 с лишним тысяч вложенных списков-вариантов множителей. После удаления одинаковых остается всего(!) 98.
Поэтому и спрашивал совета, есть ли более оптимальная возможность получения всех списков-вариантов.
При удалении внутри цикла ответ получается неверным
0
Status 418
Эксперт Python
4584 / 2350 / 601
Регистрация: 26.11.2017
Сообщений: 5,262
Записей в блоге: 3
19.08.2020, 20:18
Лучший ответ Сообщение было отмечено Gdez как решение

Решение

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def prime_divisors(n):
    a = []
    i = 2
    while i*i <= n:
        if n % i == 0:
            a.append(i)
            n //= i
        else:
            i += 1
    a.append(n)
    a.sort(reverse=True)
    return a
 
 
def solve(n):
    pr = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31]
    res = 1
    dv = prime_divisors(n)
    for x, p in zip(pr, dv):
        res *= x**(p-1)
    return res
 
print(solve(int(input())))
8 16 24 32 48 64 72 80 96 108 112 128 144 160 162 176 192 208 216 224 243 256 272 288 304 320 324 352 368 384 416 432 448 464 480 486 496 512 544 576 592 608 640 648 656 672 688 704 729 736 752 768 832 848 864 896 928 944 960 972 976 992
для этих чисел ответ не верен.
1
Эксперт Python
8851 / 4502 / 1864
Регистрация: 27.03.2020
Сообщений: 7,320
19.08.2020, 20:42  [ТС]
Для 8 у Вас выводит 30 - 1, 2, 3, 5, 6, 10, 15, 30
У меня 24 - 1,2,3,4,6,8,12,24
24 < 30
0
Status 418
Эксперт Python
4584 / 2350 / 601
Регистрация: 26.11.2017
Сообщений: 5,262
Записей в блоге: 3
19.08.2020, 20:45
Я написал для каких чисел мой код выводит не правильный ответ.
0
Эксперт Python
8851 / 4502 / 1864
Регистрация: 27.03.2020
Сообщений: 7,320
19.08.2020, 21:15  [ТС]
Извините, неверно подумал...

Добавлено через 28 минут
Интересно:
Из 63 "неверных" ответов 55 кратны 8
У оставшихся 7 - 2^2 * 3^3
2^1 * 3^4
2^0 * 3^5

2^2 * 3^4
2^1 * 3^5
2^0 * 3^6

2^2 * 3^5 = 972 (последнее)
2^1 * 3^6
2^0 * 3^7 - тоже не проходят
0
Модератор
Эксперт по электронике
 Аватар для ФедосеевПавел
8675 / 4512 / 1670
Регистрация: 01.02.2015
Сообщений: 13,949
Записей в блоге: 14
19.08.2020, 22:10
Увидел разбор "на бумаге" решения для N=16:

https://www.cyberforum.ru/cgi-bin/latex.cgi?N=16=2^4
Разложим N на множители:

1. https://www.cyberforum.ru/cgi-bin/latex.cgi?N=16=2^4
https://www.cyberforum.ru/cgi-bin/latex.cgi?X=2^{(16-1)}=2^{15}=32768

2. https://www.cyberforum.ru/cgi-bin/latex.cgi?N=16=2^4=2^3 \cdot 2^1
https://www.cyberforum.ru/cgi-bin/latex.cgi?X=2^{(8-1)} \cdot 3^{(2-1)}=2^{7} \cdot 3^{1}=384

3. https://www.cyberforum.ru/cgi-bin/latex.cgi?N=16=2^4=2^2 \cdot 2^2
https://www.cyberforum.ru/cgi-bin/latex.cgi?X=2^{(4-1)} \cdot 3^{(4-1)}=2^{3} \cdot 3^{3}=216

4. https://www.cyberforum.ru/cgi-bin/latex.cgi?N=16=2^4=2^2 \cdot 2^1 \cdot 2^1
https://www.cyberforum.ru/cgi-bin/latex.cgi?X=2^{(4-1)} \cdot 3^{(2-1)} \cdot 5^{(2-1)}=2^{3} \cdot 3^{1} \cdot 5^{1}=120

5. https://www.cyberforum.ru/cgi-bin/latex.cgi?N=16=2^4=2^1 \cdot 2^1 \cdot 2^1 \cdot 2^1
https://www.cyberforum.ru/cgi-bin/latex.cgi?X=2^{(2-1)} \cdot 3^{(2-1)} \cdot 5^{(2-1)} \cdot 7^{(2-1)}=2^{1} \cdot 3^{1} \cdot 5^{1} \cdot 7^{1}=210

После чего сравнивались варианты и выбирался ответ: 120.

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



-----------------------------------------------------
Тогда вижу решение таким.
Тут пригодится разложение на слагаемые.
И, видимо, для получения комбинаций для следующего простого делителя, придётся воспользоваться рекурсией.
Из итоговой комбинации получить число X и запомнить его для сравнения.

Возможно, какие-то условия могут ограничить рекурсию и сократить перебор.

Но именно это и реализовано в сообщении #23

Так что идей пока нет.
1
Эксперт Python
8851 / 4502 / 1864
Регистрация: 27.03.2020
Сообщений: 7,320
20.08.2020, 10:32  [ТС]
Лучший ответ Сообщение было отмечено ФедосеевПавел как решение

Решение

Все таки itertools.combinations
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
from itertools import combinations
#import numpy as np
 
def prime_divisors(n):
    a = []
    i = 2
    while i*i <= n:
        if n % i == 0:
            a.append(i)
            n //= i
        else:
            i += 1
    a.append(n)
    a.sort(reverse=True)
    return a
    
n = int(input())
npr = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61]
 
# поиск всех списков-вариантов множителей "n"
res =[]
# разложение на простые делители "n"
delit = prime_divisors(n)
tt =[n,1]
res.append(tt)
res.append(delit)
for i in range(2,len(delit)) :
    # все комбинации перебора делителей,
    # начиная с двух делителей до всех делителей
    data = list(combinations(delit, i))
    
    for j in data:
        jj = list(j)
        
        # здесь пытался применить prod от numpy,
        # но ниже при нахождении "ss" шло 
        # переполнение (????)
        
        # добавление к набору делителей
        # частного от "n" к произведению делителей
        temp = 1
        for k in jj:
            temp *= k
        temp1 = n//temp
        jj.append(temp1)
        jj.sort(reverse=True)
        
        # добавление набора "ttemp" из произведения 
        # делителей и частного от "n" к произведению
        # и удаление одинаковых списков-наборов
        if jj not in res:
            res.append(jj)
        ttemp = sorted([temp,temp1],reverse=True)
        if ttemp not in res:
            res.append(ttemp)
            
######################################
minc = int(1e300) + 1
for i in res :
    j = 0
    ss = 1
    for ii in i:
        ss *= npr[j] ** (ii-1)
        if ss > int(1e300) + 1 :
            ss = int(1e300) + 1
            break
        j += 1
    minc = min(minc,ss)
print(minc)
Отдельное спасибо еаа и ФедосеевПавел

Добавлено через 2 минуты
Время < 200 мсек
Память 300 KБ
N - проверял до 2*10^7, а не до 1000
1
Status 418
Эксперт Python
4584 / 2350 / 601
Регистрация: 26.11.2017
Сообщений: 5,262
Записей в блоге: 3
20.08.2020, 11:03
Вот нашел, похожая задача:
Acmp[точка]ru
Задача 289
0
16 / 14 / 4
Регистрация: 05.06.2019
Сообщений: 79
20.08.2020, 14:00
Недавно начал изучать язык, решил попробовать написать свой вариант
Базируется на решете Эратосфена, вроде быстро, но мне кажется что это "быдлокод"
Что думаете?

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
n = int(input('n = ')) 
dev = []  #Массив ВСЕХ делителей числа. Заполняется в другом куске кода
d = int(n / 2)
mas = list(range(d+1))  #Список чисел до n/2 так как делителей > n/2 нет
primes = []  # Массив простых делителей
 
 
def prosto():
    global dev, primes
    c = len(dev)
 
    for i in range(1, c, 1): # Поиск простых чисел начиная с первого простого делителя
        if dev[i] != 0:
            primes.append(dev[i])
            for help1 in range(i, c): #Само решето. Сравнивает значения массива ВСЕХ делителей с на кратность простым числам.
 
                for j in primes:
                    if dev[help1] % j == 0:  
                        dev[help1] = 0
 
    return primes
Миниатюры
Разложение на множители  
0
16 / 14 / 4
Регистрация: 05.06.2019
Сообщений: 79
20.08.2020, 14:05
Оу, задача то в другом состоит...
Прочитал первый пост в треде и пошел писать, хех)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
20.08.2020, 14:05

Разложение на простые множители
Разложение на простые Требуется разложить целое число N на простые множители с учётом их степени и вывести результат в порядке...

Разложение на простые множители (Время: 1 сек. Память: 16 Мб Сложность: 27%)
Требуется вывести представление целого числа N в виде произведения простых чисел. Входные данные Входной файл INPUT.TXT содержит...

Разложение на множители
Факторизацией называется разложение произвольного натурального числа n в произведение целых положительных чисел, больших 1. Два разложения...

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

Разложение на множители
Любое число может быть единственным образом разложено на простые сомножители. Написать программу для выполнения такого разложения.


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
32
Ответ Создать тему
Новые блоги и статьи
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru