Задний план
Эйлера totient
функция φ(n)
определяется как количество целых чисел меньше или равно , n
что взаимно просты с n
, то есть, число возможных значений x
в 0 < x <= n
течение которого
gcd(n, x) == 1
. У нас было
в
несколько totient - родственные проблемы и
раньше, но никогда не один , который просто его расчета.
Отображение полной функции на целые числа - OEIS A000010 .
Вызов
Учитывая целое число n > 0
, рассчитать φ(n)
. Вы можете получить ввод через аргументы командной строки, стандартный ввод, аргументы функции или что-либо еще разумное. Вы можете выдавать вывод через стандартный вывод, возвращаемые значения или что-либо еще разумное. Анонимные функции приемлемы. Вы можете предположить, что ввод не будет переполнять ваш естественный метод хранения целых чисел, например, int
в C, но вы должны поддерживать ввод до 255.
Если ваш язык имеет встроенную функцию totient, вы не можете ее использовать.
Примеры
φ(1) => 1
φ(2) => 1
φ(3) => 2
φ(8) => 4
φ(9) => 6
φ(26) => 12
φ(44) => 20
φ(105) => 48
Кратчайший ответ в байтах побеждает. Если ваш язык использует кодировку, отличную от UTF-8, укажите это в своем ответе.
EulerPhi
Ответы:
Mathematica,
2722 байтаБезымянная функция, которая принимает и возвращает целое число.
Здесь не так много объяснений, за исключением того, что
@
это префиксная нотация для вызовов функций и~...~
(слева-ассоциативная) инфиксная нотация, так что вышеупомянутое - то же самое:источник
MATL, 7 байт
Вы можете TryItOnline . Простейшая идея, сделать вектор от 1 до N и взять gcd каждого элемента с N (
Zd
делает gcd). Затем найдите, какие элементы равны 1, и суммируйте вектор, чтобы получить ответ.источник
_Zp
для тех, кто интересуется.J, 9 байт
Это основано на эссе Jsoftware о текущих функциях.
При п = р 1 е 1 ∙ р 2 е 2 ∙∙∙ р к е к , где р к является главным фактором п , функция totient ф ( п ) = ф ( р 1 е 1 ) ∙ ф ( р 2 е 2 ) φ φ ( p k e k ) = ( p 1 - 1) p 1 e 1 - 1 ∙ ( p 2 - 1) p 2e 2 - 1 ∙∙∙ ( p k - 1) p k e k - 1 .
использование
объяснение
источник
[:*/@({.(^-(^<:)){:)2&p:
требуется 24 байта, даже используя встроенную функцию для получения простых чисел и их показателей. Или, может быть, есть более короткий путь, и я его не вижу.Желе, 4 байта
Попробуйте онлайн!
объяснение
Со встроенным
Попробуйте онлайн!
объяснение
источник
Haskell, 28 байт
Использует сопоставление с образцом констант в Haskell . Уловки здесь довольно стандартны для игры в гольф, но я объясню широкой аудитории.
Выражение
gcd n<$>[1..n]
отображаетсяgcd n
на[1..n]
. Другими словами, он вычисляетgcd
сn
каждого числа от1
доn
:Отсюда желаемым выводом является количество
1
записей, но в Haskell отсутствуетcount
функция. Идиоматический способfilter
сохранить только1
букву и взять полученный результатlength
, который слишком длинен для игры в гольф.Вместо этого
filter
имитируется понимание списка[1|1<-l]
с результирующим спискомl
. Обычно, списочные выражения привязывают значения к переменной, как в[x*x|x<-l]
, но Haskell позволяет сопоставлять шаблон с, в данном случае, константой1
.Таким образом,
[1|1<-l]
генерируя1
на каждом совпадении1
, эффективно извлекая только1
из исходного списка. Вызовsum
на это дает его длину.источник
Python 2, 44 байта
Менее гольф:
Используется формула, по которой у коэффициентов Эйлера делителей
n
есть суммаn
:Затем значение
ϕ(n)
может быть рекурсивно вычислено какn
минус сумма по нетривиальным делителям. По сути, это делает инверсию Мёбиуса на единичной функции. Я использовал тот же метод в гольфе, чтобы вычислить функцию Мёбиуса .Спасибо Деннису за сохранение 1 байта с лучшим базовым регистром, распространение начального значения
+n
в+1
для каждого изn
циклов, сделанного как-~
.источник
Пайк, 5 байт
Попробуй это здесь!
источник
Регулярное выражение (ECMAScript), 131 байт
По крайней мере -12 байт благодаря Deadcode (в чате)
Попробуйте онлайн!
Выход - длина матча.
Регулярные выражения ECMAScript чрезвычайно усложняют подсчет. Любая обратная ссылка, определенная вне цикла, будет постоянной во время цикла, любая обратная ссылка, определенная внутри цикла, будет сброшена при цикле. Таким образом, единственный способ переноса состояния по итерациям цикла - использование текущей позиции совпадения. Это одно целое число, и оно может только уменьшаться (ну, позиция увеличивается, но длина хвоста уменьшается, и это то, что мы можем сделать по математике).
Учитывая эти ограничения, простой подсчет простых чисел кажется невозможным. Вместо этого мы используем формулу Эйлера для вычисления значения.
Вот как это выглядит в псевдокоде:
В этом есть две сомнительные вещи.
Во-первых, мы не сохраняем входные данные, а только текущий продукт, так как же мы можем получить основные факторы входных данных? Хитрость в том, что (N - (N / P)) имеет те же простые факторы> P, что и N. Он может получить новые простые факторы <P, но мы все равно их игнорируем. Обратите внимание, что это работает только потому, что мы перебираем простые множители от наименьшего к наибольшему, иное движение в обратном направлении завершится неудачей
Во-вторых, мы должны помнить два числа в итерациях цикла (P и N, Z не считается, поскольку он постоянен), и я только что сказал, что это невозможно! К счастью, мы можем объединить эти два числа в одном. Обратите внимание, что в начале цикла N всегда будет кратно Z, а P всегда будет меньше Z. Таким образом, мы можем просто запомнить N + P и извлечь P с помощью модуля.
Вот немного более подробный псевдокод:
И вот прокомментированное регулярное выражение:
И в качестве бонуса ...
Regex (ECMAScript 2018, количество совпадений), 23 байта
Попробуйте онлайн!
Выход - это количество совпадений. В ECMAScript 2018 вводится функция обратной длины переменной (вычисляется справа налево), которая позволяет просто считать все числа, взаимно простые с вводом.
Оказывается, это независимо тот же метод, который используется в решении Retina Лики Нун , и регулярное выражение имеет даже ту же длину ( и взаимозаменяемо ). Я оставляю это здесь, потому что может быть интересно, что этот метод работает в ECMAScript 2018 (а не только .NET).
источник
J 11 байт
использование
где
>>
STDIN и<<
STDOUT.объяснение
источник
Python> = 3,5,
766458 байтСпасибо LeakyNun за отыгрывание 12 (!) Байтов.
Спасибо Sp3000 за удаление 6 байтов.
Мне нравится, как читаемый Python. Это имеет смысл, даже благодаря игре в гольф.
источник
lambda n:sum(gcd(n,x)<2for x in range(n))
gcd
в математический модуль! Я этого не знал.Perl 6 ,
26 2422 байтаОбъяснение:
Пример:
источник
Юлия, 25 байт
Все просто -
sum
функция позволяет дать ей функцию, которую нужно применить перед суммированием - в основном это эквивалент работыmap
и затемsum
. Это напрямую подсчитывает количество относительно простых чисел меньше, чемn
.источник
Python 2, 57 байт
Проверьте это на Ideone .
Задний план
По формуле Эйлера ,
где φ обозначает функцию Эйлера, а p изменяется только по простым числам.
Чтобы определить простые числа, мы используем следствие теоремы Вильсона :
Как это работает
Всегда переменная m будет равна квадрату факториала от k - 1 . Фактически мы назвали аргументы по умолчанию k = 1 и m = 0! 2 = 1 .
Пока k ≤ n , значение
n*(k>n)
равно 0 и выполняется следующий кодor
.Напомним, что
m%k
это даст 1, если m простое число и 0, если нет. Это означает, чтоx%k<m%k
даст True тогда и только тогда, когда оба k - простое число, а x делится на k .В этом случае
(n%k<m%k)*n/k
дает n / k , и вычитая его из n заменяет его предыдущее значение на n (1 - 1 / k) , как в формуле произведения Эйлера. В противном случае(n%k<m%k)*n/k
возвращает 0, а n остается неизменным.После вычисления вышеупомянутого, мы увеличиваем k и умножаем m на «старое» значение k 2 , сохраняя, таким образом, требуемое соотношение между k и m , затем рекурсивно вызываем f с обновленными аргументами.
Как только k превышает n ,
n*(k>n)
вычисляется значение n , которое возвращается функцией.источник
Рубин, 32 байта
лямбда, которая принимает целое число n и возвращает количество равных числу целых чисел в диапазоне (1..n) с n.
источник
Брахилог , 25 байт
объяснение
Brachylog еще не имеет встроенной GCD, поэтому мы проверяем, что эти два числа не имеют общих общих факторов.
Основной предикат:
Предикат 1:
источник
Pyth, 6 байт
Попробуйте онлайн!
Попробуйте онлайн!
объяснение
источник
PowerShell v2 +, 72 байта
В PowerShell нет функции GCD, поэтому мне пришлось свернуть свою собственную.
Это принимает входные данные
$n
, затем изменяется от и1
до$n
и направляет их в цикл|%{...}
. Каждая итерация мы устанавливаем два вспомогательных переменных ,$a
и$b
затем выполнить НОДwhile
петлю. Каждая итерация мы проверить , что$b
по - прежнему не равен нулю, а затем сохранить$a%$b
до$b
и предыдущее значение ,$b
чтобы$a
для следующего цикла. Затем мы накапливаем значение$a
равно1
в нашей выходной переменной$o
. Когда цикл for завершен, мы помещаем его$o
в конвейер и вывод неявен.В качестве примера того, как
while
работает цикл, рассмотрим,$n=20
и мы находимся$_=8
. Первая проверка имеет$b=20
, поэтому мы входим в цикл. Сначала мы рассчитываем$a%$b
или8%20 = 8
, которое устанавливается$b
в то же время, что и20
устанавливается в$a
. Проверьте8=0
, и мы входим во вторую итерацию. Затем мы вычисляем20%8 = 4
и устанавливаем это значение$b
, затем устанавливаем$a
значение8
. Проверьте4=0
, и мы входим в третью итерацию. Мы вычисляем8%4 = 0
и устанавливаем это значение$b
, затем устанавливаем$a
значение4
. Проверьте0=0
и мы выходим из цикла, поэтому GCD (8,20) есть$a = 4
. Таким образом,!($a-1) = !(4-1) = !(3) = 0
так$o += 0
и не считать , что один.источник
Фактор, 50 байтов
Делает диапазон ( йота ) n и карри n в функцию, которая получает gcd xn для всех значений 0 <= x <= n , проверяет, равен ли результат 1 . Фильтр оригинальный выбор на результат ли GCD хп был 1 , и взять его длину .
источник
[ dup iota swap '[ _ gcd nip 1 = ] map sum ]
экономит 6 байт (я думаю - не очень опытный с фактором).t/f
(символами) в Factor, поэтому единственный способ реализовать это будет с помощью[ dup iota swap '[ _ gcd nip 1 = 1 0 ? ] map sum ]
, который имеет ту же самую точную длину, что и текущее решение.TYPED:
в реальный код Фактора: PJapt
-mx
,75 байтЗапустите его онлайн
-2 байта благодаря Shaggy
источник
-mx
.-m
решение, но забыл о-x
. Благодарность!Retina,
3629 байт7 байтов благодаря Мартину Эндеру.
Попробуйте онлайн!
объяснение
Есть два этапа (команды).
Начальная ступень
Это простая подстановка регулярных выражений, преобразовывающая входные данные во множество.
Например,
5
будет преобразован в11111
.Вторая стадия
Это регулярное выражение пытается сопоставить позиции, которые удовлетворяют условию (совместно с вводом), а затем возвращает количество совпадений.
источник
05AB1E, 7 байтов
Разъяснения
Попробуйте онлайн
источник
L€¿1¢
;Lʒ¿}g
;L€¿ΘO
,Common Lisp, 58 байт
Это простой цикл, который подсчитывает от 1 до заданного n и увеличивает сумму, если gcd = 1. Я использую имя функции o, поскольку t является истинным логическим значением. Не самый короткий, но довольно простой.
источник
MATLAB / Octave, 21 байт
Создает анонимную функцию с именем,
ans
которая может быть вызвана с целым числомn
в качестве единственного ввода:ans(n)
Демо онлайн
источник
Python 2 , 44 байта
При этом используется тот же метод для идентификации копримов, что и в моем ответе «Копримы до N» .
Попробуйте онлайн!
источник
n-1
вместо того1
, что заставляет его работатьn==1
.JavaScript (ES6), 53 байта
Попробуйте онлайн!
источник
C (gcc) ,
6765 байтПопробуйте онлайн!
Редактировать: Удалена временная переменная.
Edit2: -1 благодаря @HowChen
Немного меньше в гольф
источник
На самом деле, 11 байтов
Попробуйте онлайн!
объяснение
Со встроенным
Попробуйте онлайн!
источник
;╗R`╜g1=`MΣ
для того же количества байтовJavaScript (ES6), 67 байт
источник
APL, 7 байт
Это последовательность монадических функций, которая принимает целое число справа. Подход здесь очевиден: sum (
+/
) - количество раз, которое GCD входа и числа от 1 до input (⊢∨⍳
) равны 1 (1=
).Попробуй здесь
источник
Haskell,
3130 байт1 байт сохранен благодаря @Damien.
Выбирает значения с gcd = 1, сопоставляет каждое с 1, затем берет сумму.
источник
==1
на<2