Carmichael işlevini hesaplayın


36

Görev tanımı

Sayı teorisinde, Carmichael fonksiyonu  λ pozitif bir tamsayı alır  n ve getiri azından pozitif tamsayı k böylece k her tamsayı ait ıncı güç asal için n 1 modulo eşittir n .

Olumlu bir tamsayı n verildiğinde , çözümünüz λ (n) 'yi hesaplamalıdır . Bayt cinsinden en kısa kod kazanır.

Programınız isteğe bağlı olarak büyük girdiler için teorik olarak çalışmalı, ancak verimli olması gerekmez.

İpuçları

Tüm sekans X (n) olan OEIS A002322 .

Yıpranmış bir Python uygulaması gibi görünüyor

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'da pow(A, B, C)verimli bir şekilde hesaplar pow(A, B) % C.)

Test durumları

Input    Output
1        1
2        1
3        2
10       4
35       12
101      100
530      52
3010     84
6511     3056
10000    500

Teorik olarak burada ne anlama geliyor? Ben varsayabiliriz girdi n 16 bit tamsayı uyuyor? N ^ λ (n) 'in çiftle uyduğunu varsayabilir miyim ?
Dennis,

2
Evet ve evet derdim. Olduğu gibi, teorik olarak yerel türlerini keyfi kesin ve büyük gibi davranarak içerir (Ben fikir birliği olduğunu düşündüm, ama emin değilim).
Lynn,

Yanıtlar:



29

Python, 76 73 67 bayt

f=lambda n,k=1:1-any(a**-~k*~-a**k%n for a in range(n))or-~f(n,k+1)

Çevrimiçi deneyin!

Bir başka bayt döndürerek kaydedilmiş olabilir True yerine 1 .

Alternatif uygulama

Aynı yaklaşımı kullanarak, @feersum tarafından liste kavramalarını kullanmayan aşağıdaki uygulama da vardır.

f=lambda n,k=1,a=1:a/n or(a**-~k*~-a**k%n<1)*f(n,k,a+1)or-~f(n,k+1)

Bu uygulamanın O (n λ (n) ) zaman gerektirdiğini unutmayın . Aslında ise Verimlilik dramatik geliştirilebilir azalan skoru 66 bayt , ancak işlevi dönecekti Gerçek girişi için 2 .

f=lambda n,k=1,a=1:a/n or~-a**k*a**-~k%n<1==f(n,k,a+1)or-~f(n,k+1)

Arka fon

Tanımlar ve gösterim

Kullanılan tüm değişkenler tamsayıları belirtir; n , k ve a , pozitif tamsayıları belirtir ; ve p , pozitif bir prime işaret edecektir .

bir | b ise b bölünebilen bir varsa, örneğin, q, öyle ki B = qa .

a b b ( mod m), eğer a ve b , aynı kalıntı modulo m'ye sahipse, yani m | a - b .

λ (n) küçüğüdür k öyle ki bir k ≡ 1 ( mod n) - yani, öyle ki n | Bir k - 1 - herkes için a kadar aralarında asal olan n .

f (n) en küçük k'dir ki öyle bir 2k + 1 ≡ a k + 1 ( mod n) - yani n | a k + 1 (a k - 1) - tümü için a .

λ (n) ≤ f (n)

Düzeltme n ve let bir etmek be asal n .

F tanımı ile , n | a f (n) +1 (a f (n) -1) . Yana bir ve n ortak bir asal çarpanı var, ne yapmıyoruz bir f (n) +1 ve n , ima hangi n | bir f (n) -1 .

Yana λ (n) en küçük tamsayıdır k öyle | n Bir k - 1 tüm tamsayılar için bir karşı aralarında asal olan n , o kadar izler  (n) ≤ f (n) .

λ (n) = f (n)

Λ (n) ≤ f (n) eşitsizliğini zaten kurduğumuzdan , k = λ (n) 'in f , yani n | ' yi tanımlayan koşulu sağladığını doğrulamak yeterlidir. Bir λ (n) + 1 , (a λ (n) - 1) için tüm a . Bunun için p α | Bir λ (n) + 1 , (a λ (n) - 1) her s a | n .

λ (k) | λ (n) ne zaman k | n ( kaynak ), yani (a k (k) -1) (a λ (n) -λ (k) + a λ (n) -2λ (k) + ⋯ + a λ (k) + 1) = a λ (n) - 1 ve bu nedenle bir λ (k) - 1 | bir λ (n) - 1 | bir λ (n) +1 (a λ (n) -1) .

Eğer a ve p α eşdüzeyse, λ ve yukarıdakilerin tanımlarına göre , p α | a λ (p α ) - 1 | istenildiği gibi bir λ (n) +1 (a λ (n) - 1) takip eder.

Eğer a = 0 ise , tüm tamsayılar tarafından bölünebilen bir λ (n) +1 (a λ (n) - 1) = 0 olur .

Son olarak, a ve p α'nın ortak bir asal çarpan olduğu durumu düşünmeliyiz . Yana p asal, bu ima | s a . Carmichael teoremi kurar bu λ (s α ) (p = 1 -) p- α - 1 ise p> 2 ya da α <3 ve λ (s α ) p = α - 2 başka şekilde. Her durumda, λ (p α ) ≥ p α - 2 ≥ 2 α - 2 > α - 2 .

Bu nedenle λ (n) + 1 ≥ (p α ) + 1> α - 1 , yani λ (n) + 1 ≥ α ve p α | p λ (n) +1 | a λ (n) +1 | bir λ (n) +1 (a λ (n) -1) . Bu ispat tamamlar.

Nasıl çalışır

Tanımları da f (n) ve λ (n) tüm olası değerleri dikkate bir , bunun içinde o bu yalan test etmek için yeterlidir [0, ..., n - 1] .

Ne zaman f (n, k) denir, bu hesaplar bir k + 1 (a k - 1)% n tüm değerleri için bir olduğunu aralığında 0 ancak ve ancak n | bir k + 1 (a k - 1) .

Tüm hesaplanan kalıntıları sıfır ise, K = λ (n) ve anydöner yanlış , yani f (n, k) döndürür 1 .

Öte yandan, k <n (n) , 01-any(...) değerini döndürürken , f art arda k değeri ile tekrarlanır . Öncü , f (n, k + 1) ' in dönüş değerini artırır , bu yüzden [1, ..., λ (n) - 1' deki her tam sayı için 1 - f (n, λ (n)) = 1 ekleriz ] . Son sonuç λ (n) 'dir .-~


Liste anlayışı yerine en az 4 özyinelemeyle kaydedebilirsiniz: 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)(n ** λ (n) zamanını almaktan hoşlanmıyorsanız bir bayt geri ekleyin).
feersum

1
Teşekkürler! Bu arada, bir liste kavrama kullanmak yerine özyinelemenin yararını geçersiz kılan algoritmamda bir gelişme buldum.
Dennis

14

Yerleşik yerleşik Mathematica, 58 57 bayt

Hata bulduğu için Martin Ender'e teşekkürler, sonra düzeltmek için gereken baytları kurtardım!

1 bayt kaydettiğiniz için mil teşekkürler! (bana 2 gibi geldi)

Yerleşikler tamamen iyi ... ama kaba kuvvet kullanmadan uygulamak isteyenler için, işte Carmichael işlevi için bir formül:

LCM@@(EulerPhi[#^#2]/If[#==2<#2,2,1]&@@@FactorInteger@#)&

P asal ise, Carmichael işlevi λ (p ^ r), φ (p ^ r) = (p-1) * p ^ (r-1) eşittir - p = 2 ve r≥3 hariç yarısı, yani 2 ^ (r-2).

Ve n'nin asal güç faktoringi p1 ^ r1 * p2 ^ r2 * ... 'e eşitse, λ (n), {λ (p1 ^ r1), λ (p2 ^ r2), .. .}.

Çalışma zamanı, tam sayıyı ilk etapta hesaba katmaktan bir an daha fazladır.


57 bayt EulerPhialmak LCM@@(EulerPhi[#^#2]/If[#==2<#2,2,1]&@@@FactorInteger@#)&için kullanabilirsiniz .
mil

@miles güzel lekeli! 56 bayt sayıyorum, kontrol edebilir misin?
Greg Martin

Evet, 57 bayttır .
mil:

bariz olarak bile sayımı golf oynamaya çalışıyorum ....: /
Greg Martin

12

Zararlı Sayılan Şablonlar , 246 bayt

Fun<Ap<Fun<If<Eq<A<2>,T>,A<1>,And<Eq<Ap<Fun<If<A<1>,Ap<A<0>,Rem<A<2>,A<1>>,A<1>>,A<2>>>,A<1,1>,A<2>>,T>,Sub<Ap<Fun<Rem<If<A<1>,Mul<A<2,1>,Ap<A<0>,Sub<A<1>,T>>>,T>,A<1,2>>>,A<1>>,T>>,Ap<A<0>,Add<A<1>,T>,A<1,1>>,Ap<A<0>,A<1>,Sub<A<2>,T>>>>,T,A<1>>>

Adsız bir işlev (adlandırılmış işlevler değil).

Bu, C ++ derleyici örnekleme şablonları tarafından yorumlanan, unutulmuş bir esolang. Varsayılan maksimum şablon derinliği ile g++λ (35) yapabilir, ancak λ (101) yapamaz (tembel değerlendirme işleri daha da kötüleştirir).


10

Haskell, 57 56 bayt

f n=[k|k<-[1..],and[mod(m^k)n<2|m<-[1..n],gcd m n<2]]!!0

8

31
............. ._.
Maltysen

10
Böyle gülünç spesifik yapıları uygulama noktasını asla anlayamıyorum.
16'da

31
Bu neredeyse bu zorluk için özel olarak yaratılmış dile eklenmiştir. 2 gün önce Lynn tarafından taahhüt edildi, bugün
@Lynn

5
@ edc65 Bu yerleşikliğin, bu zorluğun ve bunun türevlerinin dışında oldukça yararsız olduğunu söyleme.
16'da

3
Carmichael işlevi, sayı teorisinde önemlidir (şu anda en iyi cevap yansıtıldığı gibi), bu yüzden işe yaramaz demem.
Greg Martin


6

Yakut, 59 56 bayt

->x{a=1..x
a.detect{|k|a.all?{|y|x.gcd(y)>1||y**k%x<2}}}

5

J, 28 27 bayt

[:*./@(5&p:%2^0=8&|)2^/@p:]

Carmichael işlevi λ ( n ) ve totient işlevi φ ( n ) 'dir.

Λ ( p k ) = φ ( p k ) / 2 ise p = 2 ve k > 2 başkası φ ( p k ) tanımını kullanır . Daha sonra, genel olarak n = p 1 k 1 p 2 k 2p i k i , λ ( n ) = LCM [λ ( p 1 k 1 ) λ ( p 2 k 2 ) ⋯ λ ( p i k i )] .

kullanım

Çoklu giriş / çıkışı formatlamak için kullanılan ekstra komutlar.

   f =: [:*./@(5&p:%2^0=8&|)2^/@p:]
   f 530
52
   (,.f"0) 1 2 3 10 35 101 530 3010 6511 10000
    1    1
    2    1
    3    2
   10    4
   35   12
  101  100
  530   52
 3010   84
 6511 3056
10000  500

açıklama

[:*./@(5&p:%2^0=8&|)2^/@p:]  Input: integer n
                          ]  Identity function, get n
                    2   p:   Get a table of prime/exponent values for n
                     ^/@     Raise each prime to its exponent to get the prime powers of n
[:    (            )         Operate on the prime powers
                8&|            Take each modulo 8
              0=               Test if its equal to 0, 1 if true else 0
            2^                 Raise 2 to the power of each
       5&p:                    Apply the totient function to each prime power
           %                   Divide it by the powers of 2
  *./@                       Reduce using LCM and return

Bu, 10000 (doğru 500 yerine 1000) için yanlış cevap verir ve gerçekten de her 8 için her 8 için de geçerlidir. a-1}) ne zaman a3.
Greg Martin

Bu yakalamak için teşekkürler, hatta kendi çıkışını okuyamaz görünüyor
mil

bazen yalnız değilsin .... :)
Greg Martin

5

Aslında, 30 28 25 19 26 bayt

Carmichael işlevi, λ(n)burada n = p_0**k_0 * p_1**k_1 * ... * p_a**k_a, bölünen λ(p_i**k_i)en büyük asal güçlerin en az kullanılan katları (LCM) olarak tanımlanır . Asal olduğu hariç her asal güç için göz önüne alındığında , Carmichael fonksiyonu Euler totient işlevine eşdeğerdir , kullandığımız yerine. Özel durumları için , sadece kontrol içine böler bu olursa 2 oranında programın başında, böl de.p_i**k_in2λ(n) == φ(n)φ(n)2**kk ≥ 32**3 = 8n

Ne yazık ki, aslında şu anda bir LCM yerleşikine sahip değil, bu yüzden kaba bir LCM yaptım. Golf önerileri kabul edilir. Çevrimiçi deneyin!

;7&Yu@\w`iⁿ▒`M╗2`╜@♀%ΣY`╓N

Ungolfing

         Implicit input n.
;        Duplicate n.
7&       n&7 == n%8.
Yu       Logical NOT and increment. If n%8 == 0, return 2. Else, return 1.
@\       Integer divide n by 2 if n%8==0, by 1 otherwise.
          Thus, we have dealt with the special case where p_i == 2 and e_i >= 3.
w        Full prime factorization of n as a list of [prime, exponent] lists.
`...`M   Map the following function over the prime factorization.
  i        Flatten the array, pushing exponent, then prime to the stack.
  ⁿ▒       totient(pow(prime, exponent)).
╗        Save that list of totients in register 0.
2`...`╓  Get the first two values of n where the following function f(n) is truthy.
         Those two numbers will be 0 and our LCM.
  ╜@       Push the list in register 0 and swap with our n.
  ♀%       Get n mod (every number in the list)
  Σ        Sum the modulos. This sum will be 0, if and only if this number is 0 or LCM.
  Y        Logical NOT, so that we only get a truthy if the sum of modulos is 0.
N        Grab the second number, our LCM. Implicit return.

2
Aslında, bunu sadece 19 baytta nasıl yaptığın hakkında hiçbir fikrim yok.
Buffer Over Read

@TheBitByte totientve gcdbuiltins kullanımı ile . Aslında daha lcmdoğrudan olsaydı bu daha kısa olurdu , ama o kadar umursamıyorum ve bu zaten en fazla 4 byte'ı kesecekti.
Sherlock9

1
Lcm (* a) = ürün (* a) / gcd (* a) ifadesi, * a tam olarak iki sayının bir listesi olduğunda doğrudur; ancak, genel olarak daha uzun listeler için yanlıştır (örneğin: eğer * a {6,10,15} ise, 60'ın doğru cevabı yerine 900 verir). [Bu konuda, yanlış bir durum * a da bir rakamın listesi!] Ve OP'de listelenen test vakalarının yarısından fazlası için yanlış cevap alıp almadığınızı kontrol edebilirsiniz.
Greg Martin

@GregMartin Heads up için teşekkürler. Sabit.
Sherlock9

4

JavaScript (ES6), 143 135 bayt

Düzenleme: Neil sayesinde 8 bayt kaydedildi

İşlevsel programlama kullanan bir uygulama.

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

Ungolfed ve yorum yaptı

n =>                                          // Given a positive integer n:
  (A = [...Array(n).keys()])                  // Build A = [0 ... n-1].
  .find(k =>                                  // Try to find k in [1 ... n-1] such as
    k && !c.some(c =>                         // for each coprime c: c^k ≡ 1 (mod n).
      A.slice(0, k).reduce(y =>               // We use reduce() to compute
        y * c % n, 1                          // c^k mod n.
      ) - 1                                   // Compare it with 1.
    ),                                        // The list of coprimes is precomputed
    c = A.filter(x =>                         // before the find() loop is executed:
      (                                       // for each x in [0 ... n-1], keep
        g = (x, y) => x ? g(y % x, x) : y     // only integers that verify:
      )(x, n) == 1                            // gcd(x, n) = 1
    )                                         // (computed recursively)
  ) || 1                                      // Default result is 1 (for n = 1)

gösteri

Onun için çalışır halde 6511ve 10000biraz yavaş olma eğilimindedir, ben onları burada içermez.

let f =
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

console.log(f(1));     // 1
console.log(f(2));     // 1
console.log(f(3));     // 2
console.log(f(10));    // 4
console.log(f(35));    // 12
console.log(f(101));   // 100
console.log(f(530));   // 52
console.log(f(3010));  // 84


1
JS yapabileceği 0..n-1oldukça kolay aralıkları: [...Array(n).keys()]. Bu bir değil iki özel durum gerektiriyor ama ben hala öndeyim: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
Neil

2

Ruby, 101 86 91 90 bayt

Aslında cevabımın Ruby limanı . Golf önerileri kabul edilir.

Düzenleme: -4 bayt kaldırarak aama +9 bayt 1geri döndü bir hatayı düzeltmek nil. Cyoce sayesinde -1 bayt.

require'prime'
->n{((n%8<1?n/2:n).prime_division<<[2,1]).map{|x,y|x**~-y*~-x}.reduce :lcm}

Ungolfing

require 'prime'
def carmichael(n)
  if n%8 < 1
    n /= 2
  end
  a = []
  n.prime_division.do each |x,y|
    a << x**(y-1)*(x-1)
  end
  return a.reduce :lcm
end

İhtiyacın yok a=. Ne yazık ki, dönüş nil:( = 1 n için. (n.prime_division<<[2,1])Düzeltmeleri bir golfier yolu var emin değilim..
m-Chrzan

(n%8<1?n/2:n).prime_division...başka 2 bayt kaydeder.
m-chrzan

@ m-chrzan a, daha önceki bir golf denemesinin bir kalıntısıdır. Hatırlattığın ave kafa attığın için teşekkürler 1.
Sherlock9

Sen kullanarak bir bayt kaydedebilirsiniz .reduce :lcmyerine .reduce(:lcm).
Cyoce

1

JavaScript (ES 2016) 149

Python referans uygulaması JS'ye aktarılmıştır. Bazı fantazi Pyhton yerleşikleri js'de gcdve gibi eksiktir powve dizi anlama ES 6'da standart değildir. Bu, Firefox'ta çalışır.

n=>eval('for(g=(a,b)=>b?g(b,a%b):a,p=(a,b,c)=>eval("for(r=1;b--;)r=r*a%c"),c=[for(_ of Array(i=n))if(g(i--,n)<2)i+1],k=1;c.some(x=>p(x,k,n)-1);)++k')

Daha az golf oynadı

n=>{
  g=(a,b)=>b?g(b,a%b):a
  p=(a,b,c)=>{ 
    for(r=1;b--;)
      r=r*a%c
    return r
  }
  c=[for(_ of Array(i=n)) if(g(i--,n)<2) i+1]
  for(k=1;c.some(x=>p(x,k,n)-1);)
    ++k
  return k
} 

özyinelemeli modpow daha kısadır:p=(a,b,c)=>b?a*p(a,b-1,c)%c:1;
Olivier Grégoire

1

Java, 209 207 202 194 192 bayt

Kod (96 bayt):

n->{for(int x,k=1,a;;k++){for(a=1,x=0;++x<=n&&a<2;)a=g(x,n)<2?p(x,k,n):1;if(a<2||n<2)return k;}}

Ekstra işlevler (96 bayt):

int g(int a,int b){return b<1?a:g(b,a%b);}int p(int n,int p,int m){return p<2?n:n*p(n,p-1,m)%m;}

Test ve asılsız

import java.util.Arrays;
import java.util.function.IntUnaryOperator;

public class Main2 {

  static int g(int a,int b) { // recursive gcd
    return b < 1
        ? a
        : g(b,a%b);
  }

  static int p(int n, int p, int m) { // recursive modpow
    return p < 2
      ? n
      : n * p(n, p - 1, m) % m;
  }

  public static void main(String[] args) {

    IntUnaryOperator f = n -> {
      for(int x,k=1,a;;k++) { // for each k
        for(a=1,x=0;++x<=n&&a<2;) // for each x
          a=g(x,n)<2?p(x,k,n):1; // compute modpow(x,k,n) if g(x,n)
        if(a<2||n<2) // if all modpow(x,k,n)=1. Also check for weird result for n=1.
          return k;
      }
    };

    Arrays.stream(new int[]{1, 2, 3, 10, 35, 101, 530, 3010, 6511, 10000})
        .map(f)
        .forEach(System.out::println);
  }
}

notlar

  • aolmanın kullanımı, testlerimi yapmak intiçin a kullanmam gerekenden daha kısa boolean.
  • Evet, ayrı bir işlev oluşturmaktan valueOftamamen yeni olanlar için BigIntegerdaha kısa (5, artı ONEsabit bir freebie).
  • Algoritma @Master_ex'in algoritmasından farklıdır, bu yüzden sadece bir golf repostu değildir. Ayrıca, bu algoritma gcdaynı değerler için tekrar tekrar hesaplandığından daha az verimlidir .

tıraş

  1. 209 -> 207 bayt:
    • if(...)a=...; -> a=...?...:1;
    • a==1 -> a<2
  2. 207 -> 202 bayt
    • BigIntegerGolf oynayarak gcdve modPowiçin kurtuldum int.
  3. 202 -> 194 bayt
    • döngü modPow-> özyinelemeli
  4. 194 -> 192 bayt
    • ==1-> <2(tüm test durumları için çalışıyor gözüküyor, diğer numaralar için bilmiyorum.)

Hey! Çıktının beklenen olmadığını farkettim. Beklenen sonuçlar için soruya bakınız. Şahsen, sık sık kodumu golf başlamadan önce birim testleri yazmak, yardımcı olur! Sorunun tamsayılarda modPow olabileceğini tahmin ediyorum, bu sorunu da yaşadım ve bu yüzden sonunda BigInteger kullandım.
Master_ex 21:16

Hmmm ... Şaşırdım, testlerimin her değişiklikte çalışmasına izin verdim. Neyin yanlış olduğunu kontrol edeceğim.
Olivier Grégoire

1
@Master_ex Ben düzelttim. Önceki sürüme geri dönmek tamam.
Olivier Grégoire

Özyinelemeli modpow yönteminizi poldukça zekice buluyorum . Ben de ilk başta sadece tamsayı kullanmaya çalıştım, ancak cevabımda belirttiğim gibi, hassas problemlerim vardı ve bu yüzden taşındım BigInteger(yani yerine Math.pow(3, 100)%101geri döndüm ). Uygulamanız buna bağışıklık kazanmıştır, çünkü her bir yinelemede mod gerçekleştirir. Ancak, hala bir hata muzdarip. Büyük için hala yanlış sonuçlar döndürebilir. Ayrıca, özyineleme nedeniyle , varsayılan yığın büyüklüğüne sahip büyük girdiler için kolayca oluşabilir. 60.01m pStackOverflowError
Master_ex

@Master_ex Evet, bu inttür kısıtlamaların bir sonucudur . İnts yerine uzun süre kullanabilirim, bu 8 ekstra bayt olurdu. Ancak benim görüşüme göre, tüm test durumları geçerlidir, bu yüzden böyle bırakıyorum. StackOverflowErrorolabilir, ama özyinelemeli işte böyle çalışır. Yöntemler 32 istifle sınırlandırılabilir, ancak bunlar çok daha fazla bayt kullanır. Bu uygulama kırılgan, evet, tamamen haklısın. Ancak test durumları için yeterince güçlü.
Olivier Grégoire

1

Java8 38 19 + 287 295 253 248 241 = 325 333 272 267 260 bayt

BigInteger B(int i){return new BigInteger(""+i);}int c(int...k){int n=k[0];for(k[0]=1;n>1&!java.util.stream.IntStream.range(0,n).filter(i->B(n).gcd(B(i)).equals(B(1))).allMatch(x->B(x).modPow(B(k[0]),B(n)).equals(B(1)));k[0]++);return k[0];}

İthalat, 19 bayt

import java.math.*;

açıklama

Bu yalındır bir uygulama. Yardımcı primerler hesaplanır Set pve her birinin kuvveti 1 moduloya eşit olup olmadığını kontrol etmek için kullanılır.

BigIntegerHassas sorunlar yüzünden kullanmak zorunda kaldım .

kullanım

public static void main(String[] args) {
    Carmichael c = new Carmichael();
    System.out.println(c.c(3)); // prints 2
}

Ungolfed

// returns the BigInteger representation of the given interger
BigInteger B(int i) {
    return new BigInteger(""+i);
}
// for a given integer it returns the result of the carmichael function again as interger
// so the return value cannot be larger
int c(int... k) {
    int n = k[0];
    // iterate k[0] until for all co-primes this is true: (x^n) mod n == 1, if n==1 skip the loop
    for (k[0]=1;n > 1 && !java.util.stream.IntStream.range(0, n)
                .filter(i -> B(n).gcd(B(i)).equals(B(1)))
                .allMatch(x -> B((int) x).modPow(B(k[0]), B(n)).equals(B(1)));k[0]++);
    return k[0];
}

Daha fazla golf için herhangi bir öneriniz :-) bekliyoruz

Güncelleştirme

  • Durumu koruyan işlevlerin dışında hiçbir öğe yok
  • Olivier Grégoire'nin tavsiyesini takip etti ve B()
  • k()Metot kaldırıldı ve p(eş-asal) Set.
  • İnt için gerekli döküm kaldırıldı
  • Varags eklendi ve bir süre yerine kullanın.

Unungolfed bir sürümü var mı (linebreaks, burada ve orada yorumlar, vb)
OldBunny2800 20:16 '

@ OldBunny2800: Evet, elbette. Ancak bugün daha sonra yapacağım çünkü şimdi meşgulüm!
Master_ex 20:16

@ OldBunny2800: ungolfed sürümünü :-)
ekledim

Hmmm ... Bunun ne işlev ne de program olarak sayıldığından emin değilim. Eğer bu bir işlevse, durumu dışta tutan, onu fiili bir yöntem haline getiren (işlev dış devlet olmadan saf girdi -> çıktıdır), bir programsa, bütün ana yöntem eksiktir. Yorumlarım yanlışsa, lütfen bana söyleyin! Bence k(int)bir liner olduğu ve döngüye girebileceği için döngüye dahil etmek daha iyi . Artı, O sabiti de cmetoda yerleştirilebilir . Sanırım yaparak bayt kazanacaksınız!
Olivier Grégoire

Somut olarak, seti ve sabiti yeniden işleme koyarsanız belirttiğim sorunları while(n>1&&!p.stream().allMatch(x->B((int)x).modPow(B(k), B(n)).equals(O)))bayt tıraş eder ve düzeltir. Ayrıca, Oiki kez kullanın , B(1)baytları tıraş etmek için değiştirin .
Olivier Grégoire

1

Java, 165 163 158 152 143 bayt

int l(int n){int k=1,x,a,b,t,d=1;for(;d>0;)for(d=x=0;++x<n;d=a<2&t>1?k++:d){for(a=x,b=n;b>0;b=a%b,a=t)t=b;for(t=b=1;b++<=k;t=t*x%n);}return k;}

C uygulamamın başka bir limanı .

Ideone'da dene


1

C ++, 208 200 149 144 140 134 bayt

[](int n){int k=1,x,a,b,t,d=1;for(;d;)for(d=x=0;++x<n;d=a<2&t>1?k++:d){for(a=x,b=n;t=b;a=t)b=a%b;for(t=1,b=k;b--;t=t*x%n);}return k;};

C uygulamamın bir limanı .

Ideone'da dene


0

Raket 218 bayt

(λ(n)(let((fl #f)(cl(for/list((i n) #:when(coprime? n i))i)))(for/sum((k(range 1 n))#:break fl)(set! fl #t)
(for((i(length cl))#:break(not fl))(when(not(= 1(modulo(expt(list-ref cl i)k)n)))(set! fl #f)))(if fl k 0))))

Ungolfed versiyonu:

(require math)
(define f
  (λ(n)
    (let ((fl #f)
          (cl (for/list ((i n) #:when (coprime? n i))
                i)))
             (for/sum ((k (range 1 n)) #:break fl)
               (set! fl #t)
               (for ((i (length cl)) #:break (not fl))
                 (when (not (= 1 (modulo (expt (list-ref cl i) k) n)))
                   (set! fl #f)))
               (if fl k 0)))))

Test yapmak:

(f 2) 
(f 3)
(f 10)
(f 35)
(f 101)
(f 530)
(f 3010)
(f 6511)
(f 10000)

Çıktı:

1
2
4
12
100
52
84
3056
500

0

C, 278 276 272 265 256 243 140 134 125 bayt

k,x,a,b,t,d;l(n){for(k=d=1;d;)for(d=x=0;++x<n;d=a<2&t>1?k++:d){for(a=x,b=n;t=b;a=t)b=a%b;for(t=1,b=k;b--;t=t*x%n);}return k;}

Bu yavaş modüler bir üstel algoritma kullanır, GCD'yi çok sık hesaplar ve artık hafızadan sızıntı yapmaz!

Ungolfed:

int gcd( int a, int b ) {
  int t;
  while( b ) {
    t = b;
    b = a%b;
    a = t;
  }
  return a;
}
int pw(int a,int b,int c){
  int t=1;
  for( int e=0; e<b; e++ ) {
    t=(t*a)%c;
  }
  return t;
}
int carmichael(int n) {
  int k = 1;
  for( ;; ) {
    int done = 1;
    for( int x=1; x<n; x++ ) {
      if( gcd(x,n)==1 && pw(x,k,n) != 1 ) {
        done = 0;
        k++;
      }
    }
    if( done ) break;
  }
  return k;
}

Ideone'da dene


0

Aksiyom 129 bayt

c(n)==(r:=[x for x in 1..n|gcd(x,n)=1];(v,k):=(1,1);repeat(for a in r repeat(v:=powmod(a,k,n);v~=1=>break);v<=1=>break;k:=k+1);k)

daha az golf

cml(n)==
 r:=[x for x in 1..n|gcd(x,n)=1];(v,k):=(1,1)
 repeat 
   for a in r repeat(v:=powmod(a,k,n);v~=1=>break)
   v<=1=>break
   k:=k+1
 k

Sonuçlar

(3) -> [i,c(i)] for i in [1,2,3,10,35,101,530,3010,6511,10000]
   Compiling function c with type PositiveInteger -> PositiveInteger

   (3)
   [[1,1], [2,1], [3,2], [10,4], [35,12], [101,100], [530,52], [3010,84],
    [6511,3056], [10000,500]]
                                             Type: Tuple List PositiveInteger
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.