स्वाभाविक रूप से रैखिक डायोफैंटाइन समीकरण


13

दो चरों में एक रैखिक डायोफैंटाइन समीकरण , रूप कुल्हाड़ी से + c = का समीकरण है , जहां a , b और c निरंतर पूर्णांक हैं और x और y पूर्णांक चर हैं।

कई स्वाभाविक रूप से होने वाले डायोफैंटाइन समीकरणों के लिए, x और y मात्राओं का प्रतिनिधित्व करते हैं जो नकारात्मक नहीं हो सकते।

कार्य

एक प्रोग्राम या फ़ंक्शन लिखिए जो गुणांक a , b और c को इनपुट के रूप में स्वीकार करता है और प्राकृतिक संख्याओं (0, 1, 2,…) की एक अनियंत्रित जोड़ी को लौटाता है x और y जो समीकरण ax + by = c को सत्यापित करता है , यदि ऐसी जोड़ी है। मौजूद।

अतिरिक्त नियम

  • आप इनपुट और आउटपुट के लिए कोई भी प्रारूप चुन सकते हैं जिसमें केवल वांछित पूर्णांक और, वैकल्पिक रूप से, सरणी / सूची / मैट्रिक्स / tuple / वेक्टर संकेतन शामिल हैं, जब तक आप इनपुट में किसी कोड को एम्बेड नहीं करते हैं।

  • आप मान सकते हैं कि गुणांक a और b दोनों गैर-शून्य हैं।

  • आपका कोड -2 60 और 2 60 के बीच पूर्णांकों के किसी भी ट्रिपल के लिए काम करना चाहिए ; यह मेरी मशीन पर एक मिनट के भीतर समाप्त होना चाहिए (Intel i7-3770, 16 GiB RAM)।

  • आप किसी भी अंतर्निहित इन्स का उपयोग नहीं कर सकते हैं जो डायोफैंटाइन समीकरणों को हल करते हैं और इस तरह इस कार्य को तुच्छ बनाते हैं, जैसे कि गणितज्ञ FindInstanceया FrobeniusSolve

  • आपका कोड ऐसा व्यवहार कर सकता है जब आप चाहते हैं कि कोई समाधान न मिले, क्योंकि यह समय सीमा का अनुपालन करता है और इसका आउटपुट एक वैध समाधान के साथ भ्रमित नहीं हो सकता है।

  • मानक नियम लागू होते हैं।

उदाहरण

  1. नीचे दिए गए उदाहरण समीकरण I + O को समीकरण 2x + 3y = 11 के लिए स्पष्ट करते हैं , जिसके ठीक दो वैध समाधान हैं ( (x, y) = (4,1) और (x, y) = (1,3) )।

    Input:  2 3 11
    Output: [4 1]
    
    Input:  (11 (2,3))
    Output: [3],(1)
    
  2. 2x + 3y = 2 का एकमात्र मान्य समाधान युग्म (x, y) = (1,0) है

  3. नीचे दिए गए उदाहरण समीकरण I + O को समीकरण 2x + 3y = 1 के लिए मान्य करते हैं , जिसका कोई मान्य समाधान नहीं है

    Input:  (2 3 1)
    Output: []
    
    Input:  1 2 3
    Output: -1
    
    Input:  [[2], [3], [1]]
    Output: (2, -1)
    
  4. के लिए (ए, बी, सी) = (1152921504606846883, -576460752303423433, 1) , सभी सही समाधान (एक्स, वाई) को संतुष्ट है कि - (एक्स, वाई) = (अरब, 271275648142787502 + एक 135637824071393749) कुछ गैर नकारात्मक पूर्णांक के लिए n


मुझे लगता है कि nonnegative integers पर थोड़ा और जोर देना अच्छा हो सकता है, और वास्तव में इसका दूसरा उदाहरण कोई हल नहीं है।
Sp3000

intput 1 2 3 का वैध आउटपुट है ... [1, 1]
जैक अम्मो

@ जैकेअमो: दूसरे कोड ब्लॉक में सभी उदाहरण 2x + 3y = 1 के अनुरूप हैं ।
डेनिस

कुल्हाड़ी + bx = k में यह समझने के लिए कि समाधान x> = 0 और y> = 0 होना है। तो कौन हैं ऐसे x, y> = 0 के समाधान 38 * x + 909 * y = 3?
रोजलूपी

इस तरह के मामले में शायद मुझे वापस लौटना होगा जो मौजूद नहीं है ...
RosLuP

जवाबों:


6

पायथ, 92 बाइट्स

I!%vzhK%2u?sm,ed-hd*ed/F<G2cG2@G1G+~Q,hQ_eQj9 2)J*L/vzhKtKeoSNm-VJ/RhK_*LdQsm+LdtM3/V*LhK_JQ

यह काफी राक्षस है।

इसे ऑनलाइन आज़माएँ: प्रदर्शन । इनपुट प्रारूप है c\n[a,b]और आउटपुट प्रारूप है [x,y]

इस मामले में कि कोई पूर्णांक समाधान मौजूद नहीं है, मैं कुछ भी नहीं छापूंगा, और इस मामले में कि कोई प्राकृतिक पूर्णांक समाधान मौजूद नहीं है, मैं बस एक यादृच्छिक पूर्णांक समाधान मुद्रित करूंगा।

स्पष्टीकरण (किसी न किसी अवलोकन)

  1. पहले मैं ax + by = gcd(a,b)विस्तारित यूक्लिडियन एल्गोरिथ्म का उपयोग करके समीकरण को पूर्णांक समाधान प्राप्त करूंगा ।

  2. फिर मैं पूर्णांक समाधान प्राप्त करने के लिए समाधान (मेरे गुणा aऔर उसके bसाथ c/gcd(a,b)) को संशोधित करूंगा ax + by = c। यह काम करता है, अगर c/gcd(a,b)एक पूर्णांक है। अन्यथा कोई समाधान मौजूद नहीं है।

  3. अन्य सभी पूर्णांक समाधान फार्म का a(x+n*b/d) + b(y-n*a/d) = c साथ d = gcd(a,b)पूर्णांक के लिए n। दो असमानताओं का उपयोग करना x+n*b/d >= 0और y-n*a/d >= 0मैं 6 संभावित मूल्यों को निर्धारित कर सकता हूं n। मैं उनमें से सभी 6 का प्रयास करूंगा और सबसे कम गुणांक वाले समाधान को प्रिंट करूंगा।

स्पष्टीकरण (विस्तृत)

पहला कदम समीकरण का पूर्णांक समाधान खोजना है ax' + by' = gcd(a,b)। यह विस्तारित यूक्लिडियन एल्गोरिथ्म का उपयोग करके किया जा सकता है। आप अंदाजा लगा सकते हैं कि यह विकिपीडिया पर कैसे काम करता है । एकमात्र अंतर यह है, कि 3 कॉलम ( r_i s_i t_i) का उपयोग करने के बजाय मैं 6 कॉलम ( r_i-1 r_i s_i-1 s_i t_i-1 t_i) का उपयोग करूँगा । इस तरह मुझे अंतिम दो पंक्तियों को स्मृति में नहीं रखना है, केवल अंतिम एक है।

K%2u?sm,ed-hd*ed/F<G2cG2@G1G+~Q,hQ_eQj9 2)   implicit: Q = [a,b] (from input)
                                     j9 2    convert 9 to base 2: [1,0,0,1]
                            + Q              add to Q => [a,b,1,0,0,1]
                                             this is the initial row
   u                                     )   start with G = ^ and update G repeatedly
                                             by the following expression, until
                                             the value of G doesn't change anymore
    ?                   @G1                    if G[1] != 0:
                     cG2                         split G into parts of 2
      m                                          map the parts d to:
       ,                                           the pair 
        ed                                           d[1]
          -hd*ed/F<G2                                d[0]-d[1]*G[0]/G[1]
     s                                           unfold
                                               else:
                           G                     G (don't change it, stop criterion for u)
 %2                                          take every second element
                                             we get the list [gcd(a,b),x',y']
K                                            store this list in K
                             ~Q,hQ_eQ        afterwards change Q to [Q[0],-Q[1]] = [a,-b]
                                             This will be important for the other parts. 

अब मैं इसका हल खोजना चाहता हूं ax + by = c। यह तभी संभव है, जब c mod gcd(a,b) == 0। यदि यह समीकरण संतुष्ट है, तो मैं बस के x',y'साथ गुणा कर रहा हूं c/gcd(a,b)

I!%vzhK...J*L/vzhKtK   implicit: z = c in string format (from input)
  %vzhK                evaluated(z) mod K[0] (=gcd(a,b))
I!                     if not ^ than: 
             /vzhK        c/K[0]
           *L     tK      multipy ^ to each element in K[1:] (=[x',y'])
          J               and store the result in J, this is now [x,y]

हमारे पास पूर्णांक समाधान है ax + by = c। सूचना, वह x, yया दोनों नकारात्मक हो सकती है। इसलिए हमारा लक्ष्य इन्हें गैर-नकारात्मक में बदलना है।

डायोफैंटाइन समीकरणों के बारे में अच्छी बात यह है कि हम केवल एक प्रारंभिक समाधान का उपयोग करके सभी समाधान का वर्णन कर सकते हैं। यदि (x,y)एक समाधान है, कि अन्य सभी समाधान पूर्णांक के (x-n*b/gcd(a,b),y+n*a/gcd(a,b))लिए फॉर्म के हैं n

इसलिए हम एक n, कहाँ x-n*b/gcd(a,b) >= 0और कहाँ करना चाहते हैं y+n*a/gcd(a,b >= 0। कुछ परिवर्तन के बाद हम दो असमानताओं के साथ समाप्त होते हैं n >= -x*gcd(a,b)/bऔर n >= y*gcd(a,b)/a। सूचना है कि असमानता प्रतीक एक संभावित नकारात्मक के साथ विभाजन की वजह से दूसरी दिशा में लग सकता है aया b। मैं इसके बारे में ज्यादा परवाह नहीं करता, मैं बस कहता हूं कि -x*gcd(a,b)/b - 1, -x*gcd(a,b)/b, -x*gcd(a,b)/b + 1निश्चित रूप से एक संख्या 1 असमानता को संतुष्ट करती है, और एक संख्या को y*gcd(a,b)/a - 1, y*gcd(a,b)/a, y*gcd(a,b)/a + 1असमानता 2। यह एक है n, जो दोनों असमानताओं को संतुष्ट करता है, 6 संख्याओं में से एक भी करता है।

फिर मैं (x-n*b/gcd(a,b),y+n*a/gcd(a,b))सभी 6 संभावित मूल्यों के लिए नए समाधानों की गणना करता हूं n। और मैं समाधान को उच्चतम निम्नतम मूल्य के साथ प्रिंट करता हूं।

eoSNm-VJ/RhK_*LdQsm+LdtM3/V*LhK_JQ
                               _J    reverse J => [y,x]
                           *LhK      multiply each value with K[0] => [y*gcd,x*gcd]
                         /V      Q   vectorized division => [y*gcd/a,-x*gcd/b]
                  m                  map each d of ^ to:
                      tM3              [-1,0,1]
                   +Ld                 add d to each ^
                 s                   unfold
                                     these are the possible values for n
    m                                map each d (actually n) of ^ to:
             *LdQ                      multiply d to Q => [a*n,-b*n]
            _                          reverse => [-b*n,a*n]
        /RhK                           divide by K[0] => [-b*n/gcd,a*n/gcd]
     -VJ                               vectorized subtraction with J
                                       => [x+b*n/gcd,y-a*n/gcd]
 oSN                                 order the solutions by their sorted order
e                                    print the last one

उनके द्वारा क्रमबद्ध क्रम वस्तु द्वारा क्रमबद्ध तरीके निम्न प्रकार से काम करते हैं। मैं उदाहरण का उपयोग कर रहा हूँ2x + 3y = 11

मैं 6 समाधानों में से प्रत्येक को छांटता हूं (इसे कुंजी कहा जाता है), और मूल समाधानों को उनकी कुंजियों के आधार पर क्रमबद्ध करते हैं:

solutions: [1, 3], [4, 1], [7, -1], [-5, 7], [-2, 5], [1, 3]
keys:      [1, 3], [1, 4], [-1, 7], [-5, 7], [-2, 5], [1, 3]
sort by key:
solutions: [-5, 7], [-2, 5], [7, -1], [1, 3], [1, 3], [4, 1]
keys:      [-5, 7], [-2, 5], [-1, 7], [1, 3], [1, 3], [1, 4]

यह अंत तक एक पूर्ण गैर-नकारात्मक समाधान बनाता है (यदि कोई है)।


1
  • डेनिस की टिप्पणी के बाद, जिसने मेरे पिछले विचार को उल्टा कर दिया, मुझे कोड को अपनी जड़ों से बदलना पड़ा और इसने मुझे लंबे समय तक डिबगिंग में ले लिया, और मुझे दो बार n बाइट्स की लागत दी: '(।

मतलाब (660)

a=input('');b=input('');c=input('');if((min(a*c,b*c)>c*c)&&a*c>0&&b*c>0)||(a*c<0&&b*c<0),-1,return,end,g=abs(gcd(a,b));c=c/g;a=a/g;b=b/g;if(c~=floor(c)),-1,return,end,if(c/a==floor(c/a)&&c/a>0),e=c/a-b;if(e>0),e,a,return,else,c/a,0,return,end,end,if(c/b==floor(c/b)&&c/b>0),e=c/b-a;if(e>0),b,e,return,else,0,c/b,return,end,end,f=max(abs(a),abs(b));if f==abs(a),f=b;b=a;a=f;g=0.5;end,e=(c-b)/a;f=(c-2*b)/a;if(e<0&&f<e),-1,elseif(e<0&&f>e),for(i=abs(c*a):abs((c+1)*a)),e=(c-i*b);if(mod(e,a)==0)if(g==0.5),i,e/a;else,e/a,i,end,return,end,end,else for(i=1:abs(a)),e=(c-i*b);if(e/a<0),-1,elseif(mod(e,a)==0),if(g==0.5),i,e/a,else,e/a,i,end,return,end,end,end,-1
  • ठीक है, मुझे पता है कि यह गॉल्फर्ड नहीं है, क्योंकि उस प्रकार की भाषाओं को कोड लंबाई में कमी के लिए अनुकूलित नहीं किया जाता है, लेकिन, मैं यह सुनिश्चित कर सकता हूं कि समय-जटिलता अपने सबसे अच्छे रूप में हो।

स्पष्टीकरण:

  • कोड को इनपुट के रूप में तीन इनवेरिएंट a, b, c लगते हैं, ये अंतिम गणना करने के लिए आगे बढ़ने से पहले कुछ शर्तों के अधीन हैं:

    1- अगर (a + b> c) और (a, b, c> 0) कोई हल नहीं!

    2- अगर (a + b <c), (a, b, c <0) कोई हल नहीं है!

    3 - अगर (ए, बी) सी के आम विपरीत संकेत हैं: कोई समाधान नहीं!

    4- अगर GCD (a, b) dosnt c विभाजित करता है, तो फिर कोई हल नहीं! अन्यथा, सभी वेरिएंट को GCD से विभाजित करें।

  • इसके बाद, हमें एक और शर्त की जाँच करनी होगी, इसे आसान करना चाहिए और वांछित समाधान के रास्ते को छोटा करना चाहिए।

    5- यदि c a या b को विभाजित करें, तो s = (x या y) = (c- [कुल्हाड़ी, yb]) / [b, a] = C / [b, a] + [ax, yb] / [b , ए] = एस + [एक्स, वाईबी] / [बी], जहां एस प्राकृतिक है तो एक्स / बी या बाय / ए होगा इसलिए गैर-नकारात्मक प्रत्यक्ष समाधान हैं जो क्रमशः एक्स = बी या वाई = ए हैं। (ध्यान दें कि पिछले मनमाने समाधान नकारात्मक होने पर समाधान केवल शून्य मान हो सकते हैं)

  • जब कार्यक्रम इस चरण में पहुंचता है, तो x = (c-yb) / a के लिए समाधानों की एक संकरी श्रेणी इसके बजाय बह जाती है, जो कि बधाई देने के लिए, बड़ी संख्या में बड़ी संख्या में स्वीप करने के लिए होती है, जो कि नियमित चक्र द्वारा दोहराए गए होते हैं। सबसे बड़ा खोज क्षेत्र है [xa, x + a] जहां भाजक है।

कोशिश करो


ब्यूह, बड़ी संख्या में जारी करते हैं, ठीक करते हैं (आश्चर्य जब
लोल

मुझे लगता है कि इसके अभी भी मामूली बग को ठीक करने के लिए, बड़े पूर्णांक के बारे में, मुझे अभी भी नहीं मिला कि 1152921504606846800.000000 / 576460752303423420.000000 को विभाजित करना प्राकृतिक संख्या 2 के साथ क्यों आता है, हालांकि यह अंतिम परिणाम गोल है।
अब्रिजम

ओह। मैं उस बग को ठीक करने के लिए भूल गया: पी @ नोट करने के लिए धन्यवाद @ जेकब
अब्रिजम

0

Axiom, 460 बाइट्स

w(a,b,x,u)==(a=0=>[b,x];w(b rem a,a,u,x-u*(b quo a)))
d(a,b,k)==(o:List List INT:=[];a=0 and b=0=>(k=0=>[1,1];[]);a=0=>(k=0=>[[1,0]];k rem b=0=>[1,k quo b];[]);b=0=>(k=0=>[[0,1]];k rem a=0=>[k quo a,1];[]);r:=w(a,b,0,1);q:=k quo r.1;(y,x,u,v):=(q*(r.1-r.2*a)quo b,q*r.2,b quo r.1,a quo r.1);m:=min(80,4+abs(k)quo min(abs(a),abs(b)));l:=y quo v;x:=x+l*u;y:=y-l*v;for n in -m..m repeat(t:=x+n*u;z:=y-n*v;t>=0 and z>=0 and t*a+z*b=k=>(o:=cons([t,z],o)));sort(o))

ungolf और कुछ परीक्षण

-- input a b and k for equation a*x+b*y=k
-- result one List of List of elments [x,y] of solution of  
-- that equation with x and y NNI (not negative integers) 
-- or Void list [] for no solution
diopanto(a,b,k)==
  o:List List INT:=[]
  a=0 and b=0=>(k=0=>[1,1];[])
  a=0=>(k=0=>[[1,0]];k rem b=0=>[1,k quo b];[])
  b=0=>(k=0=>[[0,1]];k rem a=0=>[k quo a,1];[])
  r:=w(a,b,0,1)
  q:=k quo r.1
  (y,x,u,v):=(q*(r.1-r.2*a)quo b,q*r.2,b quo r.1,a quo r.1)
  m:=min(80,4+abs(k)quo min(abs(a),abs(b)))
  l:=y quo v           -- center the interval
  x:=x+l*u; y:=y-l*v
  for n in -m..m repeat
     t:=x+n*u;z:=y-n*v
     t>=0 and z>=0 and t*a+z*b=k=>(o:=cons([t,z],o))
  sort(o)

 ------------------------------------------------------
(4) -> d(0,-9,0)
   (4)  [[1,0]]
                                                  Type: List List Integer
(5) -> d(2,3,11)
   (5)  [[4,1],[1,3]]
                                                  Type: List List Integer
(6) -> d(2,3,2)
   (6)  [[1,0]]
                                                  Type: List List Integer
(7) -> d(2,3,1)
   (7)  []
                                                  Type: List List Integer
(8) -> d(1152921504606846883,-576460752303423433,1)
   (8)
   [[135637824071393749,271275648142787502],
    [712098576374817182,1424197152749634385],
    [1288559328678240615,2577118657356481268],
    [1865020080981664048,3730040161963328151],
    [2441480833285087481,4882961666570175034]]
                                                  Type: List List Integer

अन्य 'समाधानों' में एक बग संभव था क्योंकि इसने अनंत समाधानों को एक सूची में सहेजने की कोशिश की थी; अब यह अधिकतम 80 समाधानों की सीमा लगा दी गई है

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