Описание задания
В теории чисел, то функция Кармайкл λ принимает положительное целое число п и возвращает наименьшее целое положительное число K , так что к -й мощности каждого целого числа взаимно простых с п равно 1 по модулю п .
Учитывая положительное целое число n , ваше решение должно вычислить λ (n) . Самый короткий код в байтах побеждает.
Ваша программа теоретически должна работать для произвольно больших входов, но не должна быть эффективной.
подсказки
Последовательность всех λ (n) является OEIS A002322 .
Реализация Python без присмотра будет выглядеть
from fractions import gcd
def carmichael(n):
coprimes = [x for x in range(1, n) if gcd(x, n) == 1]
k = 1
while not all(pow(x, k, n) == 1 for x in coprimes):
k += 1
return k
(В Python pow(A, B, C)
эффективно вычисляет pow(A, B) % C
.)
Контрольные примеры
Input Output
1 1
2 1
3 2
10 4
35 12
101 100
530 52
3010 84
6511 3056
10000 500
Ответы:
Mathematica, 16 байтов
Что ж...
источник
Python,
767367 байтПопробуйте онлайн!
Еще один байт можно сохранить, вернув True вместо 1 .
Альтернативная реализация
Используя тот же подход, @feersum также предлагает следующую реализацию, которая не использует списочные выражения.
Обратите внимание, что эта реализация требует времени O (n λ (n) ) . Эффективность может быть значительно улучшена при уменьшении оценки до 66 байт , но функция вернет True для входа 2 .
Задний план
Определения и обозначения
Все используемые переменные будут обозначать целые числа; n , k и α будут обозначать натуральные числа; и р будет обозначать положительное простое число .
а | b, если b делится на a , т. е. если существует такое q , что b = qa .
a ≡ b ( mod m), если a и b имеют одинаковый вычет по модулю m , т. е. если m | а - б .
λ (n) наименьшее k такое, что a k ≡ 1 ( mod n), т. е. такое, что n | к - 1 - для всех а , которые взаимно просты с п .
f (n) наименьшее k такое, что a 2k + 1 ≡ a k + 1 ( mod n) - т.е. такое, что n | a k + 1 (a k - 1) - для всех а .
λ (n) ≤ f (n)
Fix п и пусть а взаимно простые в п .
По определению f , n | a f (n) +1 (a f (n) - 1) . Поскольку a и n не имеют общего простого множителя, также не существует a f (n) +1 и n , из чего следует, что n | a f (n) - 1 .
Поскольку λ (n) - наименьшее целое число k такое, что n | a k - 1 для всех целых чисел a , взаимно простых с n , из этого следует, что λ (n) ≤ f (n) .
λ (n) = f (n)
Поскольку мы уже установили неравенство λ (n) ≤ f (n) , достаточно проверить, что k = λ (n) удовлетворяет условию, определяющему f , т. Е. Что n | a λ (n) +1 (a λ (n) - 1) для всех a . Для этого установим, что p α | a λ (n) +1 (a λ (n) - 1) всякий раз, когда p α | N .
λ (k) | λ (n) всякий раз, когда k | n ( источник ), поэтому (a λ (k) - 1) (a λ (n) -λ (k) + a λ (n) -2λ (k) + ⋯ + a λ (k) + 1) = a λ (n) - 1 и, следовательно, a (k) - 1 | a λ (n) - 1 | a λ (n) +1 (a λ (n) - 1) .
Если a и p α взаимно просты, по определению λ и выше, p α | a λ (p α ) - 1 | a λ (n) +1 (a λ (n) - 1) следует по желанию.
Если a = 0 , то a λ (n) +1 (a λ (n) - 1) = 0 , который делится на все целые числа.
Наконец, мы должны рассмотреть случай, когда a и p α имеют общий простой множитель. Поскольку p простое, это означает, что p | а . Теорема Кармайкла устанавливает, что λ ( pα ) = (p - 1) pα - 1, если p> 2 или α <3, и что λ ( pα ) = pα - 2 в противном случае. Во всех случаях λ (p α ) ≥ p α - 2 ≥ 2 α - 2 > α - 2 .
Therefore, λ(n) + 1 ≥ λ(pα) + 1 > α - 1, so λ(n) + 1 ≥ α and pα | pλ(n)+1 | aλ(n)+1 | aλ(n)+1(aλ(n) - 1). This completes the proof.
How it works
While the definitions of f(n) and λ(n) consider all possible values of a, it is sufficient to test those that lie in [0, ..., n - 1].
When f(n, k) is called, it computes ak+1(ak - 1) % n for all values of a in that range, which is 0 if and only if n | ak+1(ak - 1).
If all computed residues are zero, k = λ(n) and
any
returns False, so f(n, k) returns 1.On the other hand, while k < λ(n),
1-any(...)
will return 0, so f is called recursively with an incremented value of k. The leading-~
increments the return value of f(n, k + 1), so we add 1 to f(n, λ(n)) = 1 once for every integer in [1, ..., λ(n) - 1]. The final result is thus λ(n).источник
f=lambda n,k=1,a=1:a/n or(a**k*~-a**k%n<1)*f(n,k,a+2-n%2)or-~f(n,k+1)
(Add back one byte if you don't like it to take n**λ(n) time).Mathematica without built-in,
5857 bytesThanks to Martin Ender for finding an error, then saving me the bytes it took to fix it!
Thanks to miles for saving 1 byte! (which seemed like 2 to me)
Built-ins are totally fine ... but for those who want to implement it without using brute force, here's a formula for the Carmichael function:
If p is a prime, the Carmichael function λ(p^r) equals φ(p^r) = (p-1)*p^(r-1)—except when p=2 and r≥3, in which case it's half that, namely 2^(r-2).
And if the prime-power factorization of n equals p1^r1 * p2^r2 * ..., then λ(n) equals the least common multiple of { λ(p1^r1), λ(p2^r2), ...}.
Runtime is one instant more than factoring the integer in the first place.
источник
EulerPhi
to getLCM@@(EulerPhi[#^#2]/If[#==2<#2,2,1]&@@@FactorInteger@#)&
for 57 bytes.Templates Considered Harmful, 246 bytes
An unnamed function (not that there are named functions).
This is a forgotten esolang of mine which is interpreted by a C++ compiler instantiating templates. With the default max template depth of
g++
, it can do λ(35), but it can't do λ(101) (the lazy evaluation makes things worse).источник
Haskell,
5756 bytesисточник
Jelly, 2 bytes
Thank you for the builtin, @Lynn
источник
Pyth -
191817 bytesOne byte saved thanks to @TheBikingViking.
Straight up brute force.
Try it online here.
источник
f!smt
is one byte shorter.Ruby,
5956 bytesисточник
J,
2827 bytesThe Carmichael function is λ(n) and the totient function is φ(n).
Uses the definition where λ(pk) = φ(pk)/2 if p = 2 and k > 2 else φ(pk). Then, for general n = p1k1 p2k2 ⋯ piki, λ(n) = LCM[ λ(p1k1) λ(p2k2) ⋯ λ(piki) ].
Usage
Extra commands used to format multiple input/output.
Explanation
источник
Actually,
3028251926 bytesThe Carmichael function,
λ(n)
wheren = p_0**k_0 * p_1**k_1 * ... * p_a**k_a
, is defined as the least common multiple (LCM) ofλ(p_i**k_i)
for the maximal prime powersp_i**k_i
that divide inton
. Given that for every prime power except where the prime is2
, the Carmichael function is equivalent to the Euler totient function,λ(n) == φ(n)
, we useφ(n)
instead. For the special case of2**k
wherek ≥ 3
, we just check if2**3 = 8
divides inton
at the beginning of the program, and divide by 2 if it does.Unfortunately, Actually doesn't currently have an LCM builtin, so I made a brute-force LCM. Golfing suggestions welcome. Try it online!
Ungolfing
источник
totient
andgcd
builtins. This would be shorter if Actually hadlcm
directly, but I don't mind it that much and that would only knock off 4 bytes at most, anyway.JavaScript (ES6),
143135 bytesEdit: saved 8 bytes thanks to Neil
An implementation using functional programming.
Ungolfed and commented
Demo
Although it does work for
6511
and10000
, I won't include them here as it tends to be a bit slow.источник
0..n-1
ranges quite easily:[...Array(n).keys()]
. This requires not one but two special cases but I'm still ahead:n=>(a=[...Array(n).keys()]).find(k=>k&&!c.some(c=>a.slice(0,k).reduce(y=>y*c%n,1)-1),c=a.filter(x=>(g=(x,y)=>x?g(y%x,x):y)(x,n)==1))||1
Ruby,
101869190 bytesA Ruby port of my Actually answer. Golfing suggestions welcome.
Edit: -4 bytes from removing
a
but +9 bytes from fixing a bug where1
returnednil
. -1 byte thanks to Cyoce.Ungolfing
источник
a=
. Unfortunately, you returnnil
for n = 1 :(.(n.prime_division<<[2,1])
fixes that. Not sure if there's a golfier way.(n%8<1?n/2:n).prime_division...
saves another 2 bytes.a
is a remnant of an earlier golfing attempt. Thanks for the reminder abouta
and for heads up on1
..reduce :lcm
instead of.reduce(:lcm)
.JavaScript (ES 2016) 149
Python reference implementation ported to JS. Some fancy Pyhton builtin is missing in js, like
gcd
andpow
, and the array comprehension is not standard in ES 6. This works in Firefox.Less golfed
источник
p=(a,b,c)=>b?a*p(a,b-1,c)%c:1;
Java,
209207202194192 bytesCode (96 bytes):
extra functions (96 bytes):
Testing & ungolfed
Notes
a
being anint
is shorter than if I had to use aboolean
to perform my tests.valueOf
all newBigInteger
than create a separate function (there are 5, plus theONE
constant is a freebie).gcd
is computed again and again for the same values.Shaves
if(...)a=...;
->a=...?...:1;
a==1
->a<2
BigInteger
by golfinggcd
andmodPow
forint
.modPow
-> recursive==1
-><2
(seems to work for all the test cases, don't know for other numbers.)источник
p
pretty clever. I tried to use only integers at first too, but as I've mentioned in my answer, I had precision issues and that's why I've moved toBigInteger
(i.e.Math.pow(3, 100)%101
returned60.0
instead of1
). Your implementation is immune to this because it performs the mod in each iteration. However, it still suffers from a bug. For largem
p
may still return wrong results. Also, because of the recursion,StackOverflowError
may easily occur for large input with the default stack size.int
types. I could use longs instead of ints, that'd be 8 extra bytes. But in my view, all the test cases are valid so I leave it like that.StackOverflowError
can happen, but that's how recursive works. Methods exist to limit to 32 stacks, but these use many many more bytes. This implementation is fragile, yes, you are totally right. But it's strong enough for the test cases.Java8
3819 +287295253248241 =325333272267260 bytesImports, 19 bytes
Explanation
It is a straight forward implementation. The co-primes are calculated in the
Set p
and every one's kth power is used to check if it equals 1 modulo n.I had to use
BigInteger
because of precision issues.Usage
Ungolfed
Any suggestions to golf it more are welcome :-)
Update
B()
k()
method andp
(co-primes) Set.источник
k(int)
in the loop as it's a one-liner and can be done. Plus, the constant O can be put in thec
method as well. I guess you'll win bytes by doing so!while(n>1&&!p.stream().allMatch(x->B((int)x).modPow(B(k), B(n)).equals(O)))
shaves bytes and fixes the issues I mentioned if you put the set and the constant back into the method. Also, you useO
twice, replace byB(1)
to shave bytes.Java,
165 163 158 152143 bytesAnother port of my C implementation.
Try it on Ideone
источник
C++,
208 200 149 144 140134 bytesA port of my C implementation.
Try it on Ideone
источник
Racket 218 bytes
Ungolfed version:
Testing:
Output:
источник
C,
278 276 272 265 256 243 140 134125 bytesThis uses a slow modular exponentiation algorithm, computes the GCD too often and no longer leaks memory!
Ungolfed:
Try it on Ideone
источник
Axiom 129 bytes
less golfed
results
источник