Функция Эйлера
Дано натуральное число n, определите количество натуральных чисел, меньших n и взаимно простых с n.
Входные данные
Дано натуральное число n≤109.
Выходные данные
Выведите φ(n).
ввод
10
вывод
4
Dmitry
7,45811 золотых знаков24 серебряных знака52 бронзовых знака
задан 10 июн 2020 в 21:04
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
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
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
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 hcfx = 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