К содержанию

Подтема 4 из 6

Простые числа и разложение

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

Простые числа

Какое число простое и как это быстро проверить?

Простое число больше 1 и делится только на 1 и на себя. Делитель достаточно искать от 2 до √n: не нашёлся — число простое. Это тот же поиск до корня, что в подтеме 2, только останавливаемся на первом найденном делителе. Простые числа — 2, 3, 5, 7, 11, 13, …; 12 составное, а 1 — ни то ни другое: делитель у неё один.

def is_prime(n):    if n < 2:        return False    for d in range(2, isqrt(n) + 1):        if n % d == 0:            return False    return True print(is_prime(1), is_prime(2), is_prime(49), is_prime(97))
False True False True

return True стоит после цикла, а не внутри: одна неудачная попытка ещё ничего не доказывает. 25 не делится на 2, но делится на 5. У 2 цикл не выполнится ни разу — кандидатов от 2 до isqrt(2) = 1 нет, — и функция честно вернёт True.

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

Из каких простых чисел составлено число — и как это найти?

Делить на 2, пока делится, потом на 3, на 4 и дальше. Каждое удачное деление даёт простой множитель, а то, что осталось больше 1 после цикла, — последний множитель. 360 делится на 2 трижды: 360 → 180 → 90 → 45. Потом на 3 дважды: 45 → 15 → 5. Осталось простое 5. В тетради так раскладывают лесенкой:

Разложение 360 лесенкой. Каждая строка — одно деление, правый столбец — простые множители с повторениями.

Программа делает то же самое:

def prime_factors(n):    factors = []    m = n    d = 2    while d * d <= m:        while m % d == 0:            factors.append(d)            m //= d        d += 1    if m > 1:        factors.append(m)    return factors print(prime_factors(360), prime_factors(7000421))
[2, 2, 2, 3, 3, 5] [61, 114761]

m — то, что осталось от числа; m //= d — это m = m // d. Внутренний while, а не if: иначе из 360 ушла бы одна двойка из трёх. Второе число — первое из ответа задачи темы: 7 000 421 = 61 · 114 761. Посмотри по шагам, как раскладывается 1050:

  1. Начинаем: m = 1050, первый кандидат d = 2.
  2. 1050 делится на 2: записываем 2, теперь m = 525. Не меняем d: вдруг делится ещё раз.
  3. 525 на 2 не делится — переходим к d = 3.
  4. 525 делится на 3: записываем 3, теперь m = 175. Не меняем d: вдруг делится ещё раз.
  5. 175 на 3 не делится — переходим к d = 4.
  6. 175 на 4 не делится — переходим к d = 5. Составное 4 делить не может: все двойки уже удалены из m.
  7. 175 делится на 5: записываем 5, теперь m = 35. Не меняем d: вдруг делится ещё раз.
  8. 35 делится на 5: записываем 5, теперь m = 7. Снова тот же множитель — поэтому внутри стоит while, а не if.
  9. 5 · 5 = 25 больше m = 7 — цикл закончен. Если бы у 7 был делитель больше 1, хотя бы один нашёлся бы не больше √7, а такие кандидаты уже проверены.
  10. После цикла осталось m = 7. Делителей у него нет, значит, 7 простое — дописываем его. Итог: 1050 = 2 · 3 · 5 · 5 · 7.

На d = 4 ничего не делится: двойка уже вынута, и составному кандидату делить нечего. Поэтому в список попадают только простые числа, хотя d перебирает все подряд. Цикл кончается, когда d · d больше остатка, — у 1050 остаётся 7, оно и есть последний множитель.

Обоснование · необязательноПочему остаток после цикла — простое число

Если бы остаток m был составным, у него нашёлся бы делитель не больше √m — цикл до него дошёл бы и разделил. Раз цикл закончился, а m > 1, у m нет делителей до корня, значит, оно простое.

Простые делители

Условие спрашивает о простых делителях: наибольшем, их сумме или количестве. Где их взять?

В разложении: простые делители — это его множители без повторов. убирает повторы, sorted выстраивает по возрастанию.

P = sorted(set(prime_factors(84)))print(prime_factors(84), P)
[2, 2, 3, 7] [2, 3, 7]

Это быстрее, чем искать все делители и проверять каждый на простоту. Дальше всё считается по списку P — выбери, что требуется:

наименьший
P[0] → 2
наибольший
P[-1] → 7
наименьший + наибольший
P[0] + P[-1] → 9
сумма
sum(P) → 12
количество
len(P) → 3

«Не считая самого числа» важно только для простых чисел: у 97 разложение — [97], и без самого числа простых делителей не остаётся. Величину тогда берут такой, как велит условие, обычно 0. У 49 = 7 · 7 делитель 7 не равен самому числу и остаётся.

Множители и делители

«Произведение ровно двух простых множителей» и «ровно два различных простых делителя» — это одно и то же?

Нет. Множители считают с повторами — len(f), различные делители без повторов — len(set(f)). Здесь f = prime_factors(n):

ЧислоРазложениеlen(f)len(set(f))
153 · 522
93 · 321
122 · 2 · 332
302 · 3 · 533

«Ровно два простых множителя, не обязательно различных» — подходят 15 и 9. «Ровно два различных простых делителя» — 15 и 12. Слова «не обязательно различных» разрешают квадраты простых: 9 = 3 · 3, 3721 = 61 · 61.

Задача темы

Вернёмся к задаче темы:

«Напишите программу, которая перебирает целые числа, большие 7 000 000, в порядке возрастания и ищет среди них числа, представленные в виде произведения ровно двух простых множителей, не обязательно различных, каждый из которых содержит в своей записи хотя бы одну цифру 1 и хотя бы одну цифру 6. В ответе для первых пяти найденных чисел запишите само число и наибольший из его простых множителей.»

Всё готово: перебор вверх от 7 000 001 до пяти найденных, разложение каждого числа, ровно два множителя и цифры 1 и 6 в каждом из них. Проверку цифр мы написали в подтеме 1 — функция has_1_and_6.

Сначала проверим программу там, где ответ можно найти вручную. Простые числа с цифрами 1 и 6 — это 61, 163, 167, … (16 и 106 не простые). Самые маленькие произведения двух таких чисел: 61 · 61 = 3721, 61 · 163 = 9943, 61 · 167 = 10 187. Значит, после 3000 программа должна найти именно эти три числа:

n = 3001found = 0while found < 3:    f = prime_factors(n)    if len(f) == 2 and has_1_and_6(f[0]) and has_1_and_6(f[1]):        print(n, f)        found += 1    n += 1
3721 [61, 61] 9943 [61, 163] 10187 [61, 167]

Совпало, и 3721 = 61 · 61 тоже нашлось: множители не обязаны быть различными. Меняем границу и количество — и печатаем то, что просит условие, наибольший множитель:

n = 7_000_001found = 0while found < 5:    f = prime_factors(n)    if len(f) == 2 and has_1_and_6(f[0]) and has_1_and_6(f[1]):        print(n, max(f))        found += 1    n += 1
7000421 114761 7000691 2671 7000909 114769 7002643 42961 7003019 6551

Ответ: 7000421 114761 7000691 2671 7000909 114769 7002643 42961 7003019 6551. Подчёркивание в 7_000_001 только для чтения — это то же число 7000001.

Программа проверила около трёх тысяч чисел и закончила меньше чем за секунду: у большинства чисел маленький множитель находится сразу, и до √n цикл идёт редко. Проверку двух множителей можно записать и короче — : «у всех множителей из f есть 1 и 6».

Итого

  • Простоенет делителя от 2 до √n; 1 — не простое
  • Разложениеделить на d, пока делится; остаток > 1 — множитель
  • Простые делителиsorted(set(prime_factors(n)))
  • Множители с повторамиlen(f)
  • Различные делителиlen(set(f))
  • Задача темысначала маленькая граница, потом настоящая

Проверьте себя

Ответь сначала сам, потом открой ответ.

Вопрос 1
Простое ли число 221?
ОтветСкрыть ответ
Ответ
Нет: 221 = 13 · 17. Делитель 13 найдётся до √221 ≈ 14,9.
Вопрос 2
Что вернёт prime_factors(1960)? Какие у 1960 различные простые делители?
ОтветСкрыть ответ
Ответ
[2, 2, 2, 5, 7, 7]; различные простые делители — 2, 5 и 7.
Вопрос 3
Чему равны len(f) и len(set(f)) для 12 и для 9, если f = prime_factors(n)?
ОтветСкрыть ответ
Ответ
Для 12 — 3 и 2 (2 · 2 · 3), для 9 — 2 и 1 (3 · 3).
Вопрос 4
В prime_factors внутренний while m % d == 0 заменили на if. Что вернёт функция для 72?
ОтветСкрыть ответ
Ответ
[2, 3, 12] вместо [2, 2, 2, 3, 3]: каждый d делит только один раз, остаток 12 уже меньше 4 · 4, цикл кончается, и составное 12 попадает в список как «множитель».
Вопрос 5
Подходит ли под условие задачи темы число 3721 = 61 · 61, если бы граница была 3000?
ОтветСкрыть ответ
Ответ
Да: множителей ровно два, «не обязательно различных», и в записи 61 есть и 1, и 6.

Практика

Для проверки ответов нужен JavaScript. Условия, подсказки и решения доступны ниже.

Найди простые с простой суммой цифр

Найди на отрезке [251 000; 251 100] все простые числа, сумма цифр которых — тоже простое число. Для каждого выведи число и сумму его цифр.

Запишите все строки ответа подряд в одну строку через пробел: в каждой строке число и сумма его цифр.

Найди числа с простой суммой делителей

Пусть R — сумма всех натуральных делителей числа, не считая единицы и самого числа; если таких делителей нет, R = 0. Найди пять наименьших чисел, больших 2 000 000, для которых R — простое число. Для каждого выведи число и R.

Запишите все строки ответа подряд в одну строку через пробел: в каждой строке число и R.

Разложи 1960 на простые множители

Разложи на простые множители 1960.

Введите множители через пробел в порядке неубывания, с повторениями.

Найди наибольший простой делитель 999 999

Найди наибольший простой делитель числа 999 999.

Введите простой делитель.

Выпиши простые делители 990

Выпиши все различные простые делители числа 990.

Введите делители через пробел в порядке возрастания.

Найди пять чисел с суммой простых делителей на 7

Пусть S — сумма всех различных простых делителей числа, не считая самого числа. Если таких делителей нет, S = 0. Найди пять наименьших чисел, больших 2 500 000, для которых S не равно нулю, не больше 5000 и оканчивается цифрой 7. Для каждого выведи число и S.

Запишите все строки ответа подряд в одну строку через пробел: в каждой строке число и S.

Найди пять чисел с простым M больше 1000

Пусть M — сумма наименьшего и наибольшего простых делителей числа, не считая самого числа. Найди пять наименьших чисел, больших 5 000 000, для которых M больше 1000 и является простым числом. Для каждого выведи число и M.

Запишите все строки ответа подряд в одну строку через пробел: в каждой строке число и M.

Сравни простые делители и множители 72

Для числа 72 определи количество различных простых делителей и количество простых множителей с учётом повторений.

Введите два числа через пробел: количество различных простых делителей и количество простых множителей с повторениями.

Найди произведения трёх близких простых

Найди на отрезке [400 000; 700 000] все числа, которые являются произведением трёх различных простых множителей, причём наибольший и наименьший множители отличаются не больше чем на 12. Для каждого выведи число и эту разность.

Запишите все строки ответа подряд в одну строку через пробел: в каждой строке число и разность множителей.

Найди произведения двух простых с цифрой 7

Найди пять наименьших чисел, больших 3 000 000, которые представимы в виде произведения ровно двух простых множителей, не обязательно различных, причём каждый множитель содержит в записи цифру 7. Для каждого числа выведи его и наибольший из множителей.

Запишите все строки ответа подряд в одну строку через пробел: в каждой строке число и наибольший из множителей.

Задача темы: два простых множителя с цифрами 1 и 6

Задача темы. Перебирай целые числа, большие 7 000 000, в порядке возрастания и найди среди них числа, представленные в виде произведения ровно двух простых множителей, не обязательно различных, каждый из которых содержит в своей записи хотя бы одну цифру 1 и хотя бы одну цифру 6. Для первых пяти найденных чисел выведи само число и наибольший из его простых множителей.

Запишите все строки ответа подряд в одну строку через пробел: в каждой строке число и наибольший множитель.