Как найти взаимно простые числа python

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

Входные данные
Дано натуральное число n≤109.

Выходные данные
Выведите φ(n).

ввод
10
вывод
4

Dmitry's user avatar

Dmitry

7,45811 золотых знаков24 серебряных знака52 бронзовых знака

задан 10 июн 2020 в 21:04

fox_price's user avatar

1

Ну, есть тупой способ – перебором 🙂 Для небольших n вполне годится. Для больших я бы находил простые делители n, дальше методом включения-исключения искал бы количество не взаимно простых и вычитал бы из n…

Вот, я даже на Python ухитрился написать 🙂

def fi(n):
    f = n;
    if n%2 == 0:
        while n%2 == 0:
            n = n // 2;
        f = f // 2;
    i = 3
    while i*i <= n:
        if n%i == 0:
            while n%i == 0:
                n = n // i;
            f = f // i;
            f = f * (i-1);
        i = i + 2;
    if n > 1:
        f = f // n;
        f = f * (n-1);
    return f;


print(fi(int(input())));

ответ дан 11 июн 2020 в 9:47

Harry's user avatar

HarryHarry

214k15 золотых знаков117 серебряных знаков229 бронзовых знаков

Если задача не на алгоритмы, то можно воспользоваться модулем math и методом gcd – наибольший общий делитель.
Если наибольший общий делитель для числа в последовательности и общего количества натуральных чисел равен 1, то кладем его в список.
После чего возвращаем длину этого списка.

import math

def phi(n):
    result = [i for i in range(1, n + 1) if math.gcd(n, i) == 1]
    return len(result)

print(phi(10))

# OUT
# 4

ответ дан 29 июн 2022 в 4:54

Dmitry's user avatar

DmitryDmitry

7,45811 золотых знаков24 серебряных знака52 бронзовых знака

Другое оформление способа со списком без, собственно, самого списка и с не библиотечным вычислением НОД методом Евклида, вдруг кому пригодится

def Euclid(a, b): # функция Евклида
while a != 0 and b != 0:
    if a > b:
        a = a % b
    else:
        b = b % a
return max(a, b)

def EulerFunction_Euclid(n): # функция Эйлера через Евклида
result = 0
for i in range (1,n):
    if Euclid(n,i) == 1:
        result+=1
return result

n = int(input("Enter N"))
print(EulerFunction_Euclid(n))'

ответ дан 6 окт 2022 в 23:36

Александр's user avatar

I’d say your algorithm is bad. Let’s walk through a simple example, first assume:

num_1 = 2
num_2 = 3
small = 2

Running these values through your loop:

for i in range(1, small + 1):
    if num_1 % i == 0 and num_2 % i != 0:
        gcd = i

First iteration:

i = 1
2 % 1 == 0 and 3 % 1 == 0

Second (and final) iteration:

i = 2
2 % 2 = 0 and 3 % 2 != 0
    gcd = 2

Wrong answer! The gcd(2, 3) == 1

Assuming you don’t want to use the built-in math.gcd() as @oppressionslayer suggests, we can look up GCD in Wikipedia and use the recursive binary algorithm. Since we only want to know if the numbers are coprime, we can shortcut one of the statements in that algorithm (even-even test) and simply return False:

def coprime(u, v):

    # simple cases (termination)
    if u == v:
        return u == 1

    if u == 0:
        return v == 1

    if v == 0:
        return u == 1

    # look for factors of 2
    if ~u & 1:  # u is even
        if v & 1:  # v is odd
            return coprime(u >> 1, v)

        return False

    if ~v & 1:  # v is even, u is odd
        coprime(u, v >> 1)

    # reduce larger argument
    if u > v:
        return coprime(u - v, v)

    return coprime(v - u, u)

Some simple tests:

print(coprime(2, 3))  # True
print(coprime(21, 24))  # False
print(coprime(39, 115))  # True
print(coprime(115*89, 115))  # False

 import math 
x = int(input())
y = int(input())
z = int(input())
if x >= 1 and y >= 1 and z >= 1:
if math.gcd(x, y) == 1 and math.gcd(y, z) == 1 and math.gcd(x, z) == 1:
print("взаимно простые")
else:
print("не взаимно простые")

вот 🙂

Big ClawЗнаток (434)

5 месяцев назад

 def calculate_hcf(x, y): 
if x > y:
smaller = y
else:
smaller = x
for i in range(1, smaller + 1):
if ((x % i == 0) and (y % i == 0)):
hcf = i
return hcf

x = int(input())
y = int(input())
z = int(input())
if x >= 1 and y >= 1 and z >= 1:
if calculate_hcf(x, y) == 1 and calculate_hcf(y, z) == 1 and calculate_hcf(x, z) == 1:
print("взаимно простые")
else:
print("не взаимно простые")

Через функцию

#python #primes #number-theory

#python #простые числа #теория чисел

Вопрос:

Мне нужна помощь, чтобы найти мои ошибки в этой функции:

 
def is_coprime(num_1, num_2):
    """Function that returns true if 2 integers are coprime. """
    if num_1 > num_2:
        small = num_2
    else:
        small = num_1
    for i in range(1, small   1):
        if ((num_1 % i == 0) and (num_2 % i != 0)):
            gcd = i
        if (gcd == 1):
            return True
        else:
            return False

  

Надеюсь, отступ не так уж плох. Я думаю, что моя ошибка в if-условии, но я не могу понять, в чем.

Комментарии:

1. Вероятно, это лучший вопрос при обзоре кода

2. Можете ли вы исправить отступ?

3. «Надеюсь, отступ не так уж плох» — это Python, отступ имеет решающее значение 🙂

4. Если у вас есть конкретная проблема с кодом, вам следует отредактировать это в вопросе. В настоящее время вы не указываете, в чем собственно проблема.

5. «чтобы найти мои ошибки» — пожалуйста, добавьте пример ввода и ожидаемый результат, чтобы увидеть, где находятся ошибки

Ответ №1:

Взаимно простое число может быть выполнено с помощью math.gcd следующим образом:

 import math

def is_coprime(x, y):
    return math.gcd(x, y) == 1

is_coprime(39, 115)
True

is_coprime(115*89,115)                                                                                                                             
False

  

Ответ №2:

Я бы предложил такой подход:

 def divisors(x):
    return {i for i in range(2, x//2   1) if not x % i}

def coprime(x, y):
    return divisors(x).isdisjoint(divisors(y))
  

Как это работает? divisors(x) возвращает набор из всех делителей числа, большего 1.
Функция coprie(x, y) проверяет, являются ли заданные множества непересекающимися.

Комментарии:

1. range(2, x 1) Нужно ли переходить к x 1 — разве это не может быть ограничено x//2 1 и сохранить некоторые деления?

Ответ №3:

Я бы сказал, что ваш алгоритм плох. Давайте рассмотрим простой пример, сначала предположим:

 num_1 = 2
num_2 = 3
small = 2
  

Прогоняем эти значения через ваш цикл:

 for i in range(1, small   1):
    if num_1 % i == 0 and num_2 % i != 0:
        gcd = i
  

Первая итерация:

 i = 1
2 % 1 == 0 and 3 % 1 == 0
  

Вторая (и заключительная) итерация:

 i = 2
2 % 2 = 0 and 3 % 2 != 0
    gcd = 2
  

Неправильный ответ! Gcd(2, 3) == 1

Предполагая, что вы не хотите использовать встроенное, math.gcd() как предлагает @oppressionslayer, мы можем посмотреть GCD в Википедии и использовать рекурсивный двоичный алгоритм. Поскольку мы хотим знать, являются ли числа взаимно простыми, мы можем сократить одно из утверждений в этом алгоритме (четный тест) и просто вернуть False :

 def coprime(u, v):

    # simple cases (termination)
    if u == v:
        return u == 1

    if u == 0:
        return v == 1

    if v == 0:
        return u == 1

    # look for factors of 2
    if ~u amp; 1:  # u is even
        if v amp; 1:  # v is odd
            return coprime(u >> 1, v)

        return False

    if ~v amp; 1:  # v is even, u is odd
        coprime(u, v >> 1)

    # reduce larger argument
    if u > v:
        return coprime(u - v, v)

    return coprime(v - u, u)
  

Несколько простых тестов:

 print(coprime(2, 3))  # True
print(coprime(21, 24))  # False
print(coprime(39, 115))  # True
print(coprime(115*89, 115))  # False
  

Мне нужна помощь, чтобы найти ошибки в этой функции:


def is_coprime(num_1, num_2):
    """Function that returns true if 2 integers are coprime. """
    if num_1 > num_2:
        small = num_2
    else:
        small = num_1
    for i in range(1, small + 1):
        if ((num_1 % i == 0) and (num_2 % i != 0)):
            gcd = i
        if (gcd == 1):
            return True
        else:
            return False

Надеюсь, отступ не так уж и плох. Я думаю, что моя ошибка заключается в условии if, но я не могу понять, в чем именно.

3 ответа

Лучший ответ

Я бы предложил этот подход:

def divisors(x):
    return {i for i in range(2, x//2 + 1) if not x % i}

def coprime(x, y):
    return divisors(x).isdisjoint(divisors(y))

Как это работает? divisors (x) возвращает множество f всех делителей числа больше 1. Функция coprie (x, y) проверяет, не пересекаются ли заданные множества.


0

Alexander Golys
24 Авг 2020 в 09:21

Coprime можно сделать с помощью math.gcd следующим образом:

import math

def is_coprime(x, y):
    return math.gcd(x, y) == 1

is_coprime(39, 115)
True

is_coprime(115*89,115)                                                                                                                             
False


1

oppressionslayer
21 Авг 2020 в 00:39

Я бы сказал, что ваш алгоритм плохой. Давайте рассмотрим простой пример, сначала предположим:

num_1 = 2
num_2 = 3
small = 2

Выполнение этих значений через ваш цикл:

for i in range(1, small + 1):
    if num_1 % i == 0 and num_2 % i != 0:
        gcd = i

Первая итерация:

i = 1
2 % 1 == 0 and 3 % 1 == 0

Вторая (и последняя) итерация:

i = 2
2 % 2 = 0 and 3 % 2 != 0
    gcd = 2

Неправильный ответ! НОД (2, 3) == 1

Предполагая, что вы не хотите использовать встроенный math.gcd(), как предлагает @oppressionslayer, мы можем найти GCD в Википедии и использовать рекурсивный двоичный алгоритм. Поскольку нам нужно только знать, являются ли числа взаимно простыми, мы можем сократить одно из операторов этого алгоритма (тест на четность) и просто вернуть False:

def coprime(u, v):

    # simple cases (termination)
    if u == v:
        return u == 1

    if u == 0:
        return v == 1

    if v == 0:
        return u == 1

    # look for factors of 2
    if ~u & 1:  # u is even
        if v & 1:  # v is odd
            return coprime(u >> 1, v)

        return False

    if ~v & 1:  # v is even, u is odd
        coprime(u, v >> 1)

    # reduce larger argument
    if u > v:
        return coprime(u - v, v)

    return coprime(v - u, u)

Несколько простых тестов:

print(coprime(2, 3))  # True
print(coprime(21, 24))  # False
print(coprime(39, 115))  # True
print(coprime(115*89, 115))  # False


0

cdlane
24 Авг 2020 в 01:22

Добавить комментарий