मॉड्यूलर व्युत्क्रम की गणना करें


16

दो सकारात्मक संख्या को देखते हुए xऔर nसाथ x<2^n, गणना करने के लिए कम से कम समारोह लिखना x^-1 mod 2^n। दूसरे शब्दों में, लगता है yकि इस तरह के x*y=1 mod 2^n

आपका फ़ंक्शन कम से कम एक उचित समय में पूरा होना चाहिए n=64, इसलिए संपूर्ण खोज काम नहीं करेगी।

यदि व्युत्क्रम मौजूद नहीं है, तो आपको संकेत करना चाहिए कि किसी तरह कॉलर को कॉल करें (अपवाद फेंकें, एक प्रहरी मूल्य वापस लौटाएं, आदि)।

यदि आप सोच रहे हैं कि कहां से शुरू करें, तो विस्तारित यूक्लिडियन एल्गोरिथ्म का प्रयास करें ।


यह कुछ गणित सॉफ्टवेयर्स में एकल कथन होने जा रहा है
st0le

1
@ st0le: ठीक है, और आपको इस तरह के सिस्टम में इस तरह के फ़ंक्शन का उपयोग करने की अनुमति नहीं दी जाएगी। :
क्रिस जस्टर-यंग

जवाबों:


2

पायथन 95 89

cआपका कार्य है यदि कोई व्युत्क्रम नहीं है, तो रिटर्न 0 (यानी जब एक्स भी है)।

p=lambda x,y,m:y and p(x,y/2,m)**2*x**(y&1)%m or 1
c=lambda x,n:[0,p(x,2**n-1,2**n)][x%2]

3

पायथन, 29 बाइट्स

lambda x,n:pow(x,2**n-1,2**n)

यह x के लिए भी 0 लौटाता है । यह आयलर के प्रमेय का उपयोग करता है, इस अवलोकन के साथ कि 2 ^ n - 1 2 ^ ( n - 1) - 1 से विभाज्य है , पायथन के बिलियन फास्ट मॉड्यूलर एक्सप्लोरेशन के माध्यम से। यह एन या plenty००० के लिए काफी तेज है , जहां यह लगभग एक सेकंड से अधिक समय लेना शुरू करता है।



2

गोल्फस्क्रिप्ट (23 वर्ण)

{:^((1${\.**2^?%}+*}:f;

गैर-मौजूद व्युत्क्रम के लिए प्रहरी परिणाम है 0

यह यूलर प्रमेय का एक सरल अनुप्रयोग है , इसलिएxφ(2n)1(mod2n)x1x2n11(mod2n)

दुर्भाग्य से यह सीधे-सीधे गणना करने के लिए बहुत बड़ा घातीय है, इसलिए हमें एक लूप का उपयोग करना होगा और लूप के अंदर मॉड्यूलर कमी करना होगा। पुनरावृत्त चरण और हमारे पास आधार मामले का एक विकल्प है: या तोसाथx2k1=(x2k11)2×xk=1

{1\:^(@{\.**2^?%}+*}:f;

या के k=2साथ

{:^((1${\.**2^?%}+*}:f;

मैं दूसरे दृष्टिकोण पर काम कर रहा हूं, लेकिन प्रहरी अधिक कठिन है।

मुख्य अवलोकन यह है कि हम उलटा बिट का निर्माण बिट द्वारा कर सकते हैं: यदि तो x y {xy1(mod2k1) , और यदि x विषम है तो हमारे पास x (xy{1,1+2k1}(mod2k)x । (यदि आप आश्वस्त नहीं हैं, तो दो मामलों की अलग से जाँच करें)। इसलिए हम किसी भी उपयुक्त आधार मामले में शुरू करने और परिवर्तन लागू कर सकते हैं y ' = (x(y+xy1)1(mod2k)y=(x+1)y1

0x1(mod20)

x(1(x+1)nx)1(mod2n)

जहां प्रतिलोम एक ज्यामितीय अनुक्रम का योग है। मैंने खरगोश-आउट-ऑफ-द-हेट प्रभाव से बचने के लिए व्युत्पत्ति दिखाई है: इस अभिव्यक्ति को देखते हुए, यह देखना आसान है कि (दिया गया है कि ब्रैकेटेड मान एक पूर्णांक है, जो पूर्णांक के योग के रूप में इसके व्युत्पत्ति से आता है। अनुक्रम) बाईं ओर उत्पाद सही समतुल्यता वर्ग में होना चाहिए यदिx+1

यह 19-चार फ़ंक्शन देता है

{1$)1$?@/~)2@?%}:f;

x भी है। एक संभावित दिलचस्प विकल्प जो मैंने पाया है वह x&1इसके बजाय जोड़ना है 1

{1$.1&+1$?@/~)2@?%}:f;

02n1

उस एक कदम को आगे बढ़ाते हुए, हम प्रहरी सुनिश्चित कर सकते हैं।01(x+1)n11n :

{1$.1&*)1$?@/~)2@?%}:f;

nn x f

{..1&*)2$?\/~)2@?%}:f;

1

रूबी - 88 वर्ण

फ़ंक्शन का उपयोग करें f

def e a,b;a%b==0?[0,1]:(x,y=e(b,a%b);[y,x-(y*(a/b))])end
def f x,n;e(x,2**n)[0]*(x%2)end

केवल लिंक किए गए विकी पृष्ठ से पुनरावर्ती फ़ंक्शन, त्रुटि पर 0 देता है।


आप कुछ अक्षरों को e: inlining से बचा सकते हैं (e=->a,b{...})[x,2**n][0]। के a%b<1बजाय परीक्षण द्वारा एक चरित्र को भी बचा सकता है a%b==0
हिस्टोक्रेट

1

हास्केल, 42 बाइट्स

_!1=1
x!n|r<-x!div(n+1)2=(2-r*x)*r`mod`2^n

हेंसल की लेम्मा पर आधारित एक एल्गोरिथ्म का उपयोग करना जो हर पुनरावृत्ति में अंकों की संख्या को दोगुना करता है, यह एक सेकंड के तहत लगभग 30 मिलियन तक एन के लिए चलता है !


1

अजगर , 9 बाइट्स

.^Et^2Q^2

यहाँ यह कोशिश करो!

रिवर्स ऑर्डर में इनपुट लेता है। या, 9 बाइट्स:.^EtK^2QK :।

व्याख्या

^ ^ ^ ^ 2Q ^ 2 - पूर्ण कार्यक्रम।

। ^ - पॉव फ़ंक्शन। अजगर (पाव) में भी यही है।
  ई - दूसरा इनपुट।
    ^ 2Q - और 2 ^ पहला इनपुट।
   t - घटाया हुआ।
       ^ 2 - और 2 ^ पहला इनपुट फिर से।

0

जीएपी, 39 बाइट्स

f:=function(x,n)return 1/x mod 2^n;end;

f(x,n)का प्रतिलोम देता xसापेक्ष 2^nऔर एक त्रुटि संदेश देता है

Error, ModRat: for <r>/<s> mod <n>, <s>/gcd(<r>,<s>) and <n> must be coprime

यदि कोई व्युत्क्रम मौजूद नहीं है।

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