कारमाइकल फ़ंक्शन की गणना करें


36

कार्य विवरण

संख्या सिद्धांत रूप में, कारमाइकल समारोह  λ एक सकारात्मक पूर्णांक लेता  n और रिटर्न कम से कम सकारात्मक पूर्णांक कश्मीर ताकि कश्मीर प्रत्येक पूर्णांक के मई के बिजली coprime के लिए एन के बराबर होती है 1 सापेक्ष एन

एक सकारात्मक पूर्णांक n को देखते हुए , आपके समाधान को λ (n) की गणना करनी चाहिए । बाइट्स में सबसे छोटा कोड जीतता है।

आपके कार्यक्रम को सैद्धांतिक रूप से बड़े इनपुट के लिए काम करना चाहिए, लेकिन कुशल होने की आवश्यकता नहीं है।

टिप्स

सभी λ (n) का क्रम OEIS A002322 है

एक अनियंत्रित अजगर कार्यान्वयन जैसा दिखेगा

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

(अजगर में, 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

यहाँ सैद्धांतिक रूप से क्या मतलब है? क्या मैं मान सकता हूं कि इनपुट n 16-बिट पूर्णांक में फिट बैठता है? क्या मैं मान सकता हूं कि n ^ λ (n) एक डबल में फिट बैठता है?
डेनिस

2
हाँ और हाँ, मैं कहूँगा। के रूप में, सैद्धांतिक रूप से अपने मूल प्रकार का ढोंग शामिल है मनमाने ढंग से सटीक और बड़े हैं (मुझे लगता है कि आम सहमति थी, लेकिन मुझे यकीन नहीं है)।
लिन

जवाबों:



29

पायथन, 76 73 67 बाइट्स

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

इसे ऑनलाइन आज़माएं!

1 के बजाय ट्रू वापस करके एक और बाइट को बचाया जा सकता है ।

वैकल्पिक कार्यान्वयन

उसी दृष्टिकोण का उपयोग करते हुए, @ फ़ेर्सम द्वारा निम्नलिखित कार्यान्वयन भी है जो सूची समझ का उपयोग नहीं करता है।

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)

ध्यान दें कि इस कार्यान्वयन के लिए O (n λ (n) ) समय की आवश्यकता है। वास्तव में 66 बाइट्स में स्कोर कम करते हुए दक्षता में सुधार किया जा सकता है , लेकिन इनपुट 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)

पृष्ठभूमि

परिभाषाएँ और संकेतन

सभी नियोजित चर पूर्णांक को निरूपित करेंगे; n , k , और α सकारात्मक पूर्णांक निरूपित करेगा ; और पी एक सकारात्मक अभाज्य को निरूपित करेगा ।

ए | ख यदि से विभाज्य है एक , अर्थात अगर वहाँ क्ष ऐसी है कि ख = क्यूए

a b ( mod m) यदि a और b में एक ही अवशेष modulo m है , अर्थात, यदि m | ए - बी

λ (एन) सबसे छोटी है कश्मीर ऐसी है कि एक कश्मीर ≡ 1 ( आधुनिक एन) - यानी, ऐसी है कि एन | a k - 1 - सभी के लिए जो कि पुलिस से n है

f (n) सबसे छोटा k है जैसे कि एक 2k + 1 k a k + 1 ( mod n) - अर्थात, ऐसा n | a k + 1 (a k - 1) - सभी के लिए a

λ (n) (f (n)

फिक्स n और जाने एक हो coprime एन

एफ की परिभाषा के द्वारा , एन | a f (n) +1 (a f (n) - 1) । के बाद से एक और n एक आम प्रधानमंत्री कारक नहीं है, न करना एक च (एन) +1 और n है, जो कि तात्पर्य n | a f (n) - १

चूँकि λ (n) सबसे छोटा पूर्णांक k होता है जैसे कि n | a k - 1 सभी पूर्णांकों के लिए जो कि n के लिए सहानुभूति है , यह इस प्रकार है कि λ (n)) f (n)

λ (n) = f (n)

चूँकि हम पहले ही असमानता λ (n) n f (n) स्थापित कर चुके हैं , यह सत्यापित करने के लिए पर्याप्त है कि k = λ (n) f को परिभाषित करने वाली स्थिति को संतुष्ट करता है , अर्थात, n | a λ (n) +1 (a λ (n) - 1) सभी के लिए a । इस प्रयोजन के लिए, हम उस की स्थापना करेंगे पी अल्फा | एक λ (एन) +1 (एक λ (एन) - 1) जब भी पी अल्फा | n

λ (के) | λ (n) जब भी k | n ( स्रोत ), तो (एक λ (k) - 1) (एक λ (n) -λ (k) + एक λ (n) -२ (λ (k) + ⋯ + एक λ (k) + १) = १ λ (n) - 1 और इसलिए, एक λ (k) - 1 | a λ (n) - 1 | a λ (n) +1 (एक λ (n) - 1)

यदि a और p α कोप्रेम हैं, तो λ और उपरोक्त की परिभाषा से, p α | एक λ (पी α ) - 1 | एक λ (n) +1 (एक λ (n) - 1) निम्नानुसार, वांछित।

यदि एक = 0 , तो एक λ (n) +1 (एक λ (n) - 1) = 0 , जो सभी पूर्णांकों द्वारा विभाज्य है।

अंत में, हमें उस मामले पर विचार करना चाहिए जहाँ a और p α का एक सामान्य अभाज्य गुणक है। चूँकि p अभाज्य है, इसका अर्थ है कि p | aकारमाइकल का प्रमेय स्थापित करता है कि λ (p α ) = (p - 1) p α - 1 यदि p> 2 या α <3 और वह λ (p α ) = p α - 2 अन्यथा। सभी मामलों में, λ (p α ) α p α - 2 α 2 α - 2 > α - 2

इसलिए, λ (n) + 1 λ (p α ) + 1> α - 1 , इसलिए λ (n) + 1 α α और p α | p λ (n) +1 | a λ (n) +1 | a λ (n) +1 (एक λ (n) - 1) । इससे प्रमाण पूरा हो जाता है।

यह काम किस प्रकार करता है

जबकि की परिभाषा च (एन) और λ (एन) के सभी संभव मूल्यों पर विचार एक है, यह उन है कि में झूठ का परीक्षण करने के लिए पर्याप्त है [0, ..., n - 1]

जब च (एन, ट) कहा जाता है, यह गणना करता है एक k + 1 (एक कश्मीर - 1)% n के सभी मानों के लिए एक है कि सीमा है, जो है में 0 यदि और केवल यदि n | a k + 1 (a k - 1)

यदि सभी गणना किए गए अवशेष शून्य हैं, तो k = λ (n) और anyरिटर्न गलत है , इसलिए f (n, k) रिटर्न 1

दूसरी ओर, जबकि k <λ (n) , 01-any(...) लौटेगा , इसलिए f को k के एक संवर्धित मूल्य के साथ पुनरावर्ती कहा जाता है । प्रमुख वेतन वृद्धि की वापसी मान च (एन, k + 1) , तो हम जोड़ने के 1 करने के लिए F (n, λ (एन)) = 1 में हर पूर्णांक के लिए एक बार [1, ..., λ (एन) - 1 ] हो गया । अंतिम परिणाम इस प्रकार λ (n) है-~


आप सूची बोध के बजाय पुनरावृत्ति के साथ कम से कम 4 बचा सकते हैं: 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) समय लेना पसंद नहीं करते हैं तो एक बाइट जोड़ें)
feersum

1
धन्यवाद! इस बीच, मैंने अपने एल्गोरिथ्म में एक सुधार पाया जो सूची समझ का उपयोग करने के बजाय पुनरावर्ती के लाभ को कम करता है।
डेनिस

14

अंतर्निहित बिना मैथमेटिका, 58 57 बाइट्स

एक त्रुटि खोजने के लिए मार्टिन एंडर के लिए धन्यवाद, फिर मुझे बाइट्स बचाने के लिए इसे ठीक करने के लिए लिया!

1 बाइट बचाने के लिए मीलों धन्यवाद! (जो मुझे 2 जैसा लगता था)

बिल्ट-इन पूरी तरह से ठीक हैं ... लेकिन उन लोगों के लिए जो इसे क्रूर बल का उपयोग किए बिना लागू करना चाहते हैं, यहां कारमाइकल फ़ंक्शन का एक सूत्र है:

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

यदि p एक प्रधान है, तो कार्माइकल फ़ंक्शन λ (p ^ r) बराबर p (p ^ r) = (p-1) * p ^ (r-1) - सिवाय जब p = 2 और r p3, जिस स्थिति में यह आधा है, अर्थात् 2 ^ (आर -2)।

और यदि n- p1 ^ r1 * P2 ^ r2 * ... की प्रधान-शक्ति का गुणन, तो λ (n) {λ (p1 ^ r1), λ (P2 ^ r2), के कम से कम सामान्य गुणकों के बराबर है। ।}।

रनटाइम पहले में पूर्णांक को फैक्टर करने से एक पल अधिक है।


आप 57 बाइट्स EulerPhiप्राप्त करने के लिए उपयोग कर सकते हैं LCM@@(EulerPhi[#^#2]/If[#==2<#2,2,1]&@@@FactorInteger@#)&
मील

@ मीलों अच्छी तरह से देखा! मैं 56 बाइट्स गिनता हूं, क्या आप जांच कर सकते हैं?
ग्रेग मार्टिन

हाँ, यह 57 बाइट्स है
मील

स्पष्ट रूप से मैं अपनी गिनती के लिए भी प्रयास करता हूं ....:
ग्रेग मार्टिन

12

हानिकारक माना जाने वाले टेम्पलेट , 246 बाइट्स

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>>>

एक अनाम फ़ंक्शन (ऐसा नहीं है कि नामित कार्य हैं)।

यह मेरा एक भूला हुआ पलायन है, जिसकी व्याख्या C ++ कंपाइलर इंस्टेंटिमिटिंग टेम्प्लेट द्वारा की जाती है। की डिफ़ॉल्ट अधिकतम टेम्पलेट गहराई के साथ g++, यह λ (35) कर सकता है, लेकिन यह λ (101) (आलसी मूल्यांकन चीजों को बदतर बनाता है) नहीं कर सकता है।



8

31
………… ._।
माल्टीसेन

10
मैं इस तरह के हास्यास्पद विशिष्ट अंतर्निहित इंस को लागू करने के बिंदु को कभी नहीं समझता।
घातक

31
यह इस चुनौती के लिए विशेष रूप से बनाई गई भाषा के लगभग एक अतिरिक्त है। 2 दिन पहले लिन द्वारा प्रतिबद्ध, आज @Lynn द्वारा चुनौती
edc65

5
@ edc65 यह उल्लेख करने के लिए नहीं कि यह बिल्ट-इन इस चुनौती और इसके व्युत्पन्न के बाहर बहुत बेकार है।
घातक

3
खैर, संख्या सिद्धांत में कारमाइकल फ़ंक्शन महत्वपूर्ण है (जैसा कि वर्तमान में शीर्ष उत्तर दर्शाता है), इसलिए मैं इसे बेकार नहीं कहूंगा।
ग्रेग मार्टिन

6

पायथ - 19 18 17 बाइट्स

एक बाइट ने @TheBikingViking के लिए धन्यवाद बचाया।

सीधे बल बल।

f!sm*t.^dTQq1iQdQ

इसे यहाँ ऑनलाइन आज़माएँ


f!smtएक बाइट कम है
बाइकिंग बाइकिंग

@ TheBikingViking ओह, हाँ धन्यवाद
Maltysen

मेरी आँखों में हूर है, कैसे इस अजगर है ..? इसे फिर भी बहुत पसंद किया गया :)
योहन ओबैदिया


5

जे, 28 27 बाइट्स

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

कारमाइकल फ़ंक्शन λ ( n ) है और कुल कार्य n ( n ) है।

परिभाषा का उपयोग करता है जहां λ ( p k ) = p ( p k ) / 2 यदि p = 2 और k > 2 और ) ( p k )। फिर, सामान्य के लिए n = पी 1 कश्मीर 1 पी 2 कश्मीर 2पी मैं k मैं , λ ( एन ) = एलसीएम [λ ( पी 1 कश्मीर 1 ) λ ( पी 2 कश्मीर 2 ) ⋯ λ ( पी मैं k मैं )] ।

प्रयोग

एकाधिक इनपुट / आउटपुट को प्रारूपित करने के लिए उपयोग की जाने वाली अतिरिक्त कमांड।

   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

व्याख्या

[:*./@(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

यह 10000 (सही 500 के बजाय 1000) के लिए गलत उत्तर देता है, और वास्तव में प्रत्येक 8. 8 में से कई के लिए एक अजीब प्रधान है, और λ (2 ^ ए) = 2 ^ {a-2} (2 ^ {नहीं) a-1}) जब a3।
ग्रेग मार्टिन

पकड़ने के लिए धन्यवाद, लगता है कि मैं अपना खुद का आउटपुट भी नहीं पढ़ सकता
मील

आप कभी-कभी अकेले नहीं होते हैं .... :)
ग्रेग मार्टिन

5

दरअसल, 30 28 25 19 26 बाइट्स

कारमाइकल फ़ंक्शन को, λ(n)जहां विभाजित करने वाली अधिकतम प्रमुख शक्तियों n = p_0**k_0 * p_1**k_1 * ... * p_a**k_aके λ(p_i**k_i)लिए कम से कम सामान्य एकाधिक (LCM) के रूप में परिभाषित किया p_i**k_iगया है n। यह देखते हुए कि प्रत्येक प्रमुख शक्ति के लिए, जहां प्रधानमंत्री है 2, सिवाय कारमाइकल फ़ंक्शन यूलर टोटिएंट फ़ंक्शन के बराबर है λ(n) == φ(n), हम φ(n)इसके बजाय उपयोग करते हैं। के विशेष मामले के लिए 2**kजहां k ≥ 3, हम बस अगर जाँच 2**3 = 8विभाजित में nकार्यक्रम की शुरुआत है, और विभाजन पर 2 से अगर यह होता है।

दुर्भाग्य से, वास्तव में वर्तमान में एक एलसीएम बिल्डिन नहीं है, इसलिए मैंने एक ब्रूट-फोर्स एलसीएम बनाया। गोल्फ सुझाव का स्वागत करते हैं। इसे ऑनलाइन आज़माएं!

;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
वास्तव में, मुझे नहीं पता कि आपने केवल 19 बाइट्स में यह कैसे किया।
बफ़र ओवर पढ़ें

@ TheBitByte totientऔर gcdबिल्डिंस के उपयोग के साथ । यह छोटा होगा यदि वास्तव में lcmसीधे था , लेकिन मुझे इससे कोई आपत्ति नहीं है और यह केवल 4 बाइट्स को ही बंद करेगा, वैसे भी।
शर्लक

1
यह दावा कि lcm (* a) = उत्पाद (* a) / gcd (* a) सत्य है जब * a बिल्कुल दो नंबरों की सूची है; हालाँकि, यह सामान्य रूप से लंबी सूचियों के लिए गलत है (उदाहरण: अगर * a {6,10,15} है, तो यह 60 के सही उत्तर के बजाय 900 देता है)। [उस बात के लिए, यह गलत है * एक एक नंबर की एक सूची है साथ ही!] और आप जांच सकते हैं कि आपको ओपी में सूचीबद्ध आधे से अधिक परीक्षण मामलों के लिए गलत उत्तर मिल गया है।
ग्रेग मार्टिन

@GregMartin सिर के लिए धन्यवाद। फिक्स्ड।
शर्लक

4

जावास्क्रिप्ट (ईएस 6), 143 135 बाइट्स

संपादित करें: नील के लिए 8 बाइट्स बचाए गए

कार्यात्मक प्रोग्रामिंग का उपयोग करके एक कार्यान्वयन।

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

असहमति और टिप्पणी की

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)

डेमो

यद्यपि यह काम करता है 6511और 10000, मैं उन्हें यहाँ शामिल नहीं करूंगा क्योंकि यह थोड़ा धीमा हो जाता है।

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
जेएस 0..n-1काफी आसानी से रेंज कर सकते हैं [...Array(n).keys()]:। इसके लिए एक नहीं बल्कि दो विशेष मामलों की आवश्यकता है लेकिन मैं अभी भी आगे हूं: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
नील

2

रूबी, 101 86 91 90 बाइट्स

मेरे वास्तव में उत्तर का एक रूबी बंदरगाह । गोल्फ सुझाव का स्वागत करते हैं।

संपादित करें: -4 बाइट्स हटाने से aलेकिन +9 बाइट्स एक बग को ठीक करने से जहां 1वापस लौटे nil। -1 बाइट साओस के लिए धन्यवाद।

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

आप की जरूरत नहीं है a=। दुर्भाग्य से, आप niln = 1 :( के लिए लौटते हैं । (n.prime_division<<[2,1])ठीक करता है। यकीन नहीं होता कि कोई गोल्फ रास्ता है।
m-chrzan

(n%8<1?n/2:n).prime_division...एक और 2 बाइट्स बचाता है।
m-chrzan

@ m-chrzan aएक पूर्व गोल्फ प्रयास का अवशेष है। के बारे में aऔर सिर पर अनुस्मारक के लिए धन्यवाद 1
शर्लक

आप .reduce :lcmइसके बजाय का उपयोग करके एक बाइट बचा सकते हैं .reduce(:lcm)
19

1

जावास्क्रिप्ट (ईएस 2016) 149

पायथन संदर्भ कार्यान्वयन को जेएस में रखा गया। कुछ फैंसी पाइथन बिलिन जेएस में गायब है, जैसे gcdऔर pow, और सरणी समझ ईएस 6. में मानक नहीं है। यह फ़ायरफ़ॉक्स में काम करता है।

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')

कम गोल्फ वाला

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
} 

पुनरावर्ती मोडपो कम है:p=(a,b,c)=>b?a*p(a,b-1,c)%c:1;
ओलिवियर

1

जावा, 209 207 202 194 192 बाइट्स

कोड (96 बाइट्स):

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;}}

अतिरिक्त कार्य (96 बाइट्स):

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;}

परीक्षण और अपुष्ट

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);
  }
}

टिप्पणियाँ

  • यदि मेरे परीक्षणों को पूरा करने के लिए मुझे इसका उपयोग करना पड़ता है तो इससे कम aहोने का उपयोग intकम है boolean
  • हां, यह एक अलग फ़ंक्शन बनाने की तुलना में valueOfसभी नए BigIntegerसे छोटा है (5 हैं, साथ ही ONEस्थिर एक फ्रीबी है)।
  • एल्गोरिथ्म @Master_ex 'एल्गोरिथ्म से अलग है, इसलिए यह सिर्फ एक गोल्फ रिपॉस्ट नहीं है। इसके अलावा, यह एल्गोरिथ्म बहुत कम कुशल है क्योंकि gcdसमान मूल्यों के लिए बार-बार गणना की जाती है।

शेव

  1. 209 -> 207 बाइट्स:
    • if(...)a=...; -> a=...?...:1;
    • a==1 -> a<2
  2. 207 -> 202 बाइट्स
    • गॉट से छुटकारा BigIntegerगोल्फ से gcdऔर modPowके लिए int
  3. 202 -> 194 बाइट्स
    • लूपिंग modPow-> पुनरावर्ती
  4. 194 -> 192 बाइट्स
    • ==1-> <2(सभी परीक्षण मामलों के लिए काम करता है, अन्य संख्याओं के लिए नहीं जानता।)

अरे! मैंने देखा है कि आउटपुट अपेक्षित नहीं है। अपेक्षित परिणाम के लिए प्रश्न देखें। निजी तौर पर, मैं अक्सर अपने कोड को शुरू करने से पहले इकाई परीक्षण लिखता हूं, इससे मदद मिलती है! मुझे लगता है कि समस्या पूर्णांक पर modPow हो सकती है, मुझे भी यह समस्या थी और इसलिए मैंने आखिर में BigInteger का उपयोग किया।
Master_ex

हम्म् ... मुझे आश्चर्य है, मैंने अपने परीक्षणों को हर बदलाव पर चलने दिया। मैं जांच करूंगा कि क्या गलत है।
ओलिवियर ग्रेजायर

1
@Master_ex मैंने इसे ठीक किया। पिछले संस्करण पर वापस जाना ठीक है।
ओलिवियर ग्रेजायर

मैं अपने पुनरावर्ती modpow विधि pबहुत चालाक पाते हैं । मैंने पहली बार में केवल पूर्णांक का उपयोग करने की कोशिश की, लेकिन जैसा कि मैंने अपने उत्तर में उल्लेख किया है, मेरे पास सटीक मुद्दे थे और इसीलिए मैं BigInteger(यानी इसके बजाय Math.pow(3, 100)%101वापस लौटा हूं )। आपका कार्यान्वयन इसके लिए प्रतिरक्षा है क्योंकि यह प्रत्येक पुनरावृत्ति में मॉड प्रदर्शन करता है। हालाँकि, यह अभी भी एक बग से ग्रस्त है। बड़े के लिए अभी भी गलत परिणाम लौट सकते हैं। इसके अलावा, पुनरावृत्ति के कारण, डिफ़ॉल्ट स्टैक आकार के साथ बड़े इनपुट के लिए आसानी से हो सकता है। 60.01m pStackOverflowError
मास्टर_एक्स

@Master_ex हाँ, यह intप्रकारों के लिए प्रतिबंध का एक परिणाम है । मैं चींटियों के बजाय लोंगो का उपयोग कर सकता था, जो कि 8 अतिरिक्त बाइट्स होंगे। लेकिन मेरे विचार में, सभी परीक्षण मामले वैध हैं इसलिए मैं इसे उसी तरह छोड़ देता हूं। StackOverflowErrorहो सकता है, लेकिन यह है कि कैसे पुनरावर्ती काम करता है। 32 स्टैक को सीमित करने के लिए तरीके मौजूद हैं, लेकिन ये कई और बाइट्स का उपयोग करते हैं। यह कार्यान्वयन नाजुक है, हां, आप पूरी तरह से सही हैं। लेकिन यह परीक्षण मामलों के लिए पर्याप्त मजबूत है।
ओलिवियर ग्रेजायर

1

जावा 8 38 19 + 287 295 253 248 241 = 325 333 272 267 260 बाइट्स

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];}

आयात, 19 बाइट्स

import java.math.*;

व्याख्या

यह एक सीधे आगे कार्यान्वयन है। सह-अपराधों की गणना की जाती है Set pऔर प्रत्येक की kth शक्ति का उपयोग यह जांचने के लिए किया जाता है कि क्या यह 1 modulo n के बराबर है।

मुझे BigIntegerसटीक मुद्दों के कारण उपयोग करना पड़ा ।

प्रयोग

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];
}

यह अधिक स्वागत है गोल्फ के लिए किसी भी सुझाव :-)

अद्यतन करें

  • राज्य को बनाए रखने वाले कार्यों के बाहर कोई तत्व नहीं
  • ओलिवियर ग्रेजायर की सलाह का पालन किया और 1 बाइट से बचाया B()
  • k()विधि और p(सह-primes) सेट को निकाल दिया गया ।
  • निकालने के लिए आवश्यक नहीं कास्टिंग int।
  • समय के बजाय जोड़े गए और उपयोग करें।

आप एक ungolfed संस्करण हो सकता है (linebreaks के साथ, यहाँ और वहाँ टिप्पणियाँ, आदि)
OldBunny2800

@ OldBunny2800: हाँ, ज़रूर। हालाँकि, मैं इसे आज बाद में करूँगा क्योंकि अब मैं व्यस्त हूँ!
Master_ex

@ OldBunny2800: मैंने एक असंगत संस्करण जोड़ा :-)
Master_ex

हम्म ... मुझे यकीन नहीं है कि यह मायने रखता है क्योंकि यह न तो एक समारोह है और न ही एक कार्यक्रम है। यदि यह एक फ़ंक्शन है, तो इसके बाहर ऐसे तत्व हैं जो राज्य को बनाए रखते हैं, इसे एक वास्तविक विधि बनाते हैं (फ़ंक्शन शुद्ध इनपुट है-> बाहरी राज्य के बिना आउटपुट), यदि यह एक कार्यक्रम है, तो पूरी मुख्य विधि गायब है। अगर मेरी व्याख्या गलत है, तो कृपया मुझे बताएं! मुझे लगता है k(int)कि लूप में शामिल करना बेहतर है क्योंकि यह एक-लाइनर है और इसे किया जा सकता है। साथ ही, स्थिर ओ को cविधि में भी रखा जा सकता है । मुझे लगता है कि आप ऐसा करके बाइट जीत लेंगे!
ओलिवियर ग्रेगोइरे

वस्तुतः, while(n>1&&!p.stream().allMatch(x->B((int)x).modPow(B(k), B(n)).equals(O)))शेव बाइट्स और सुधारों के मुद्दों अगर आप सेट और विधि में लगातार वापस रख मैं उल्लेख किया है। इसके अलावा, आप Oदो बार उपयोग करते हैं , B(1)शेव बाइट्स द्वारा प्रतिस्थापित करते हैं ।
ओलिवियर ग्रेगोइरे



0

रैकेट 218 बाइट्स

(λ(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 संस्करण:

(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)))))

परिक्षण:

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

आउटपुट:

1
2
4
12
100
52
84
3056
500

0

सी, 278 276 272 265 256 243 140 134 125 बाइट्स

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;}

यह एक धीमी मॉड्यूलर घातांक एल्गोरिथ्म का उपयोग करता है, जीसीडी की गणना अक्सर करता है और अब मेमोरी लीक नहीं करता है!

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 पर इसे आज़माएं


0

एक्सिओम 129 बाइट्स

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)

कम गोल्फ वाला

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

परिणाम

(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
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.