एक साथ चार वर्ग


19

लैग्रेंज के चार वर्ग प्रमेय हमें बताते हैं कि किसी भी प्राकृतिक संख्या को चार वर्ग संख्या के योग के रूप में दर्शाया जा सकता है। आपका कार्य एक प्रोग्राम लिखना है जो ऐसा करता है।

इनपुट: एक प्राकृतिक संख्या (1 बिलियन से नीचे)

आउटपुट: चार संख्याएँ जिनके वर्ग उस संख्या तक आते हैं (ऑर्डर मायने नहीं रखता है)

नोट: आप एक क्रूर बल खोज करने की जरूरत नहीं है! यहाँ और यहाँ का विवरण । यदि कोई ऐसा कार्य है जो इस समस्या को हल करता है (मैं निर्धारित करूँगा), तो इसकी अनुमति नहीं है। स्वचालित मुख्य कार्य और वर्गमूल की अनुमति है। यदि एक से अधिक प्रतिनिधित्व है तो कोई भी ठीक है। यदि आपने पाशविक बल करना चुना है, तो उसे उचित समय (3 मिनट) के भीतर चलना चाहिए

नमूना इनपुट

123456789

नमूना उत्पादन (या तो ठीक है)

10601 3328 2 0
10601 3328 2

अगर मैं अपने कोड को छोटा बनाता हूं तो मैं ब्रूट फोर्स कर सकता हूं?
मार्टिन एंडर

@ m.buettner हां, लेकिन इसे बड़ी संख्या को संभालना चाहिए
qwr

@ m.buettner पोस्ट पढ़ें, 1 बिलियन से नीचे कोई भी प्राकृतिक संख्या
qwr

आह क्षमा करें।
मार्टिन एंडर

2
@ इस मामले में डेनिस नेचुरल नंबरों में शामिल नहीं है
19

जवाबों:


1

सीजेएम, 50 बाइट्स

li:NmF0=~2/#:J(_{;)__*N\-[{_mqJ/iJ*__*@\-}3*])}g+p

मेरा तीसरा (और अंतिम, मैं वादा करता हूं) जवाब देता हूं। यह दृष्टिकोण प्राइमो के उत्तर पर आधारित है ।

CJam दुभाषिया में इसे ऑनलाइन आज़माएं ।

प्रयोग

$ cjam 4squares.cjam <<< 999999999
[189 31617 567 90]

पृष्ठभूमि

  1. प्राइमो के अपडेट किए गए एल्गोरिदम को देखने के बाद, मुझे यह देखना था कि सीजेएम कार्यान्वयन कैसे स्कोर करेगा:

    li{W):W;:N4md!}g;Nmqi)_{;(__*N\-[{_mqi__*@\-}3*])}g+2W#f*p
    

    केवल 58 बाइट्स! यह एल्गोरिथ्म लगभग निरंतर समय में किया जाता है और विभिन्न मूल्यों के लिए बहुत भिन्नता प्रदर्शित नहीं करता है N। आइए बदलते हैं कि ...

  2. floor(sqrt(N))शुरू करने 1और घटाने के बजाय , हम शुरू और वेतन वृद्धि कर सकते हैं । यह 4 बाइट्स बचाता है।

    li{W):W;:N4md!}g;0_{;)__*N\-[{_mqi__*@\-}3*])}g+2W#f*p
    
  3. के Nरूप में व्यक्त करने के बजाय 4**a * b, हम इसे के रूप में व्यक्त कर सकते हैं p**(2a) * b- जहां 1 pसबसे छोटा प्रमुख कारक है N- 1 और बाइट को बचाने के लिए।

    li_mF0=~2/#:J_*/:N!_{;)__*N\-[{_mqi__*@\-}3*])}g+Jf*p
    
  4. पिछला संशोधन हमें कार्यान्वयन को थोड़ा बदलने की अनुमति देता है (एल्गोरिथ्म को छूने के बिना): इसके Nद्वारा विभाजित p**(2a)करने और समाधान को गुणा करने के बजाय p**a, हम संभव समाधान को कई गुना तक सीमित कर सकते हैं p**a। यह 2 और बाइट्स बचाता है।

    li:NmF0=~2/#:J!_{;J+__*N\-[{_mqJ/iJ*__*@\-}3*])}g+`
    
  5. p**aएक अतिरिक्त बाइट की बचत के गुणकों में पहले पूर्णांक तक सीमित नहीं है ।

    li:NmF0=~2/#:J(_{;)__*N\-[{_mqJ/iJ*__*@\-}3*])}g+`
    

अंतिम एल्गोरिथ्म

  1. खोजें aऔर bऐसा है N = p**(2a) * b, जहां bएक से अधिक नहीं है p**2और pका सबसे छोटा प्रमुख कारक है N

  2. सेट करें j = p**a

  3. सेट करें k = floor(sqrt(N - j**2) / A) * A

  4. सेट करें l = floor(sqrt(N - j**2 - k**2) / A) * A

  5. सेट करें m = floor(sqrt(N - j**2 - k**2 - l**2) / A) * A

  6. यदि N - j**2 - k**2 - l**2 - m**2 > 0, सेट करें j = j + 1और चरण 3 पर वापस जाएं।

इसे निम्नानुसार लागू किया जा सकता है:

li:N          " Read an integer from STDIN and save it in “N”.                        ";
mF            " Push the factorization of “N”. Result: [ [ p1 a1 ] ... [ pn an ] ]    ";
0=~           " Push “p1” and “a1”. “p1” is the smallest prime divisor of “N”.        ";
2/#:J         " Compute p1**(a1/2) and save the result “J”.                           ";
(_            " Undo the first two instructions of the loop.                          ";
{             "                                                                       ";
  ;)_         " Pop and discard. Increment “J” and duplicate.                         ";
  _*N\-       " Compute N - J**2.                                                     ";
  [{          "                                                                       ";
    _mqJ/iJ*  " Compute K = floor(sqrt(N - J**2)/J)*J.                                ";
    __*@      " Duplicate, square and rotate. Result: K   K**2   N - J**2             ";
    \-        " Swap and subtract. Result: K   N - J**2 - K**2                        ";
  }3*]        " Do the above three times and collect in an array.                     ";
  )           " Pop the array. Result: N - J**2 - K**2 - L**2 - M**2                  ";
}g            " If the result is zero, break the loop.                                ";
+p            " Unshift “J” in [ K L M ] and print a string representation.           ";

मानक

मैंने अपने इंटेल कोर i7-3770 पर 999,999,999 तक सभी सकारात्मक पूर्णांकों पर सभी 5 संस्करण चलाए हैं, निष्पादन समय मापा और समाधान खोजने के लिए आवश्यक पुनरावृत्तियों को गिना।

निम्न तालिका एक पूर्णांक के लिए पुनरावृत्तियों और निष्पादन समय की औसत संख्या दर्शाती है:

Version               |    1    |    2    |    3    |    4    |    5
----------------------+---------+---------+---------+---------+---------
Number of iterations  |  4.005  |  28.31  |  27.25  |  27.25  |  41.80
Execution time [µs]   |  6.586  |  39.69  |  55.10  |  63.99  |  88.81
  1. केवल 4 पुनरावृत्तियों और 6.6 माइक्रो सेकंड प्रति पूर्णांक पर, प्राइमो का एल्गोरिथ्म अविश्वसनीय रूप से तेज है।

  2. शुरू करने floor(sqrt(N))से अधिक समझ में आता है, क्योंकि यह हमें शेष तीन वर्गों के योग के लिए छोटे मूल्यों के साथ छोड़ देता है। जैसा कि अपेक्षित था, 1 से शुरू होना बहुत धीमा है।

  3. यह बुरी तरह से लागू किए गए अच्छे विचार का एक शास्त्रीय उदाहरण है। वास्तव में कोड आकार को कम करने के लिए, हम इस पर भरोसा करते हैं mF, जो पूर्णांक को कारक बनाता है N। हालांकि संस्करण 3 को संस्करण 2 की तुलना में कम पुनरावृत्तियों की आवश्यकता है, यह व्यवहार में बहुत धीमा है।

  4. यद्यपि एल्गोरिथ्म नहीं बदलता है, संस्करण 4 बहुत धीमा है। ऐसा इसलिए है क्योंकि यह एक अतिरिक्त फ़्लोटिंग पॉइंट डिवीज़न और प्रत्येक पुनरावृत्ति में एक पूर्णांक गुणन करता है।

  5. इनपुट के लिए N = p**(2a) ** b, एल्गोरिथ्म 5 को (k - 1) * p**a + 1पुनरावृत्तियों की आवश्यकता होगी , जहां पुनरावृत्तियों kकी संख्या एल्गोरिथ्म 4 की आवश्यकता है। यदि k = 1या a = 0, यह कोई फर्क नहीं पड़ता।

    हालाँकि, प्रपत्र का कोई भी इनपुट 4**a * (4**c * (8 * d + 7) + 1)काफी खराब प्रदर्शन कर सकता है। प्रारंभिक मूल्य के लिए j = p**a, N - 4**a = 4**(a + c) * (8 * d + 7)इसलिए इसे तीन वर्गों के योग के रूप में व्यक्त नहीं किया जा सकता है। इस प्रकार, k > 1और कम से कम p**aपुनरावृत्तियों की आवश्यकता होती है।

    शुक्र है, प्राइमो का मूल एल्गोरिथ्म अविश्वसनीय रूप से तेज़ और है N < 1,000,000,000। सबसे खराब स्थिति मुझे हाथ से मिल सकती है 265,289,728 = 4**10 * (4**1 * (7 * 8 + 7) + 1), जिसके लिए 6,145 पुनरावृत्तियों की आवश्यकता है। निष्पादन का समय मेरी मशीन पर 300 एमएस से कम है। प्रिमो के एल्गोरिदम के कार्यान्वयन की तुलना में औसतन यह संस्करण 13.5 गुना धीमा है।


"के Nरूप में व्यक्त करने के बजाय 4**a * b, हम इसे व्यक्त कर सकते हैं p**(2a) * b।" यह वास्तव में एक सुधार है । मुझे यह शामिल करना पसंद था, लेकिन यह बहुत लंबा था (आदर्श सबसे बड़ा पूर्ण वर्ग कारक खोजना है)। "1 से शुरू होकर वेतन वृद्धि 4 बाइट्स बचाती है।" यह निश्चित रूप से धीमा है। किसी भी सीमा के लिए रनटाइम 4-5 गुना लंबा है। "999,999,999 तक के सभी सकारात्मक पूर्णांकों में 24.67 घंटे लगते हैं, जो प्रति पूर्णांक 0.0888 मिलीसेकंड का औसत निष्पादन समय देता है।" पर्ल ने पूरी रेंज को उखाड़ने के लिए केवल 2.5 घंटे का समय लिया, और पायथन अनुवाद 10x तेज है;)
प्राइमो

@primo: हाँ, तुम सही हो। द्वारा विभाजित p**aकरना एक सुधार है, लेकिन यह एक छोटा है। 1 से शुरू होने पर सबसे बड़ा पूर्ण वर्ग कारक द्वारा विभाजित करना एक बड़ा अंतर बनाता है ; वर्गमूल के पूर्णांक भाग से शुरू करते समय यह अभी भी एक सुधार है। इसे लागू करने पर केवल दो और बाइट का खर्च आएगा। एबिसमाल का निष्पादन समय मेरी अकल्पनीयताओं के कारण लगता है, सीजेएम के लिए नहीं। मैं दीवार के समय को मापने के बजाय पुनरावृत्तियों की गणना करते हुए सभी एल्गोरिदम (आपके द्वारा प्रस्तावित एक सहित) के लिए परीक्षणों को फिर से चलाऊंगा। आइए देखें कि कितना समय लगता है ...
डेनिस

सबसे बड़ा वर्ग कारक ढूँढना केवल 2 अतिरिक्त बाइट्स खर्च होता है ?! ये किस तरह का जादू है?
Primo

@प्रिमो: यदि पूर्णांक स्टैक पर है, तो 1\इसे 1 (संचयकर्ता) के साथ स्वैप करें, mFइसके फैक्टराइजेशन को धकेलता है और {~2/#*}/प्रत्येक प्राइम फैक्टर को दो से विभाजित अपने घातांक तक बढ़ाता है, फिर इसे संचायक से गुणा करता है। अपने एल्गोरिथ्म के प्रत्यक्ष कार्यान्वयन के लिए, जो केवल 2 बाइट्स जोड़ता है। छोटा अंतर मुख्य रूप से अजीब तरीके से होता है क्योंकि मुझे 4 के प्रतिपादक को ढूंढना था, क्योंकि सीजेएम नहीं लगता (प्रतीत होता है) थोड़ी देर के लिए है ...
डेनिस

वैसे भी, बेंचमार्क समाप्त हो गया। 1.00 घंटे के निष्पादन समय के साथ, सबसे बड़े वर्ग कारक को खोजने के बिना सभी 1,000,000 पूर्णांकों को जोड़ने के लिए आवश्यक पुनरावृत्तियों की कुल संख्या 4,004,829,417 है। सबसे बड़े वर्ग कारक से विभाजित होने से पुनरावृत्ति गिनती घटकर 3,996,724,799 हो जाती है, लेकिन यह समय 6.7 घंटे तक बढ़ा देती है। ऐसा लगता है कि चौराहों को खोजने से ज्यादा समय लगता है ...
डेनिस

7

FRACTRAN: 156 98 अंश

चूंकि यह एक क्लासिक नंबर थ्योरी समस्या है, इसको हल करने के लिए इससे बेहतर तरीका क्या हो सकता है!

37789/221 905293/11063 1961/533 2279/481 57293/16211 2279/611 53/559 1961/403 53/299 13/53 1/13 6557/262727 6059/284321 67/4307 67/4661 6059/3599 59/83 1/59 14279/871933 131/9701 102037079/8633 14017/673819 7729/10057 128886839/8989 13493/757301 7729/11303 89/131 1/89 31133/2603 542249/19043 2483/22879 561731/20413 2483/23701 581213/20687 2483/24523 587707/21509 2483/24797 137/191 1/137 6215941/579 6730777/965 7232447/1351 7947497/2123 193/227 31373/193 23533/37327 5401639/458 229/233 21449/229 55973/24823 55973/25787 6705901/52961 7145447/55973 251/269 24119/251 72217/27913 283/73903 281/283 293/281 293/28997 293/271 9320827/58307 9831643/75301 293/313 28213/293 103459/32651 347/104807 347/88631 337/347 349/337 349/33919 349/317 12566447/68753 13307053/107143 349/367 33197/349 135199/38419 389/137497 389/119113 389/100729 383/389 397/383 397/39911 397/373 1203/140141 2005/142523 2807/123467 4411/104411 802/94883 397/401 193/397 1227/47477 2045/47959 2863/50851 4499/53743 241/409 1/241 1/239

फॉर्म 2 एन × 193 के इनपुट में ले जाता है और 3 × 5 बी × 7 सी × 11 डी आउटपुट करता है । यदि आपके पास वास्तव में अच्छा दुभाषिया है तो 3 मिनट में चला सकते हैं । शायद।

... ठीक है, वास्तव में नहीं। यह FRACTRAN में करने के लिए इतनी मजेदार समस्या थी कि मुझे इसे आजमाना पड़ा । जाहिर है, यह प्रश्न का उचित समाधान नहीं है क्योंकि यह समय की आवश्यकताओं को पूरा नहीं करता है (यह बलों को क्रूरता देता है) और यह मुश्किल से गोल्फ भी है, लेकिन मैंने सोचा कि मैं इसे यहां पोस्ट करूंगा क्योंकि यह हर दिन नहीं है कि कोडगॉल्फ प्रश्न FRACTRAN में किया जा सकता है;)

संकेत

कोड निम्नलिखित छद्म-पायथन के बराबर है:

a, b, c, d = 0, 0, 0, 0

def square(n):
    # Returns n**2

def compare(a, b):
    # Returns (0, 0) if a==b, (1, 0) if a<b, (0, 1) if a>b

def foursquare(a, b, c, d):
    # Returns square(a) + square(b) + square(c) + square(d)

while compare(foursquare(a, b, c, d), n) != (0, 0):
    d += 1

    if compare(c, d) == (1, 0):
        c += 1
        d = 0

    if compare(b, c) == (1, 0):
        b += 1
        c = 0
        d = 0

    if compare(a, b) == (1, 0):
        a += 1
        b = 0
        c = 0
        d = 0

7

गणितज्ञ 61 66 51

तीन तरीके दिखाए गए हैं। केवल पहला दृष्टिकोण समय की आवश्यकता को पूरा करता है।


1-FindInstance (51 char)

यह एकल समाधान समीकरण देता है।

FindInstance[a^2 + b^2 + c^2 + d^2 == #, {a, b, c, d}, Integers] &

उदाहरण और समय

FindInstance[a^2 + b^2 + c^2 + d^2 == 123456789, {a, b, c, d}, Integers] // AbsoluteTiming

{0.003584, {{a -> 2600, b -> 378, c -> 10468, d -> 2641}}}

FindInstance[a^2 + b^2 + c^2 + d^2 == #, {a, b, c, d}, Integers] &[805306368]

{0.004437, {{a -> 16384, b -> 16384, c -> 16384, d -> 0}}}


2-IntegerPartitions

यह भी काम करता है, लेकिन गति की आवश्यकता को पूरा करने के लिए बहुत धीमा है।

f@n_ := Sqrt@IntegerPartitions[n, {4}, Range[0, Floor@Sqrt@n]^2, 1][[1]]

Range[0, Floor@Sqrt@n]^2के वर्गमूल n(विभाजन में सबसे बड़ा संभव वर्ग) से कम सभी वर्गों का सेट है ।

{4}nवर्गों के उपर्युक्त सेट से 4 तत्वों से मिलकर पूर्णांक विभाजन की आवश्यकता है ।

1, समारोह के भीतर IntegerPartitionsपहला समाधान देता है।

[[1]]बाहरी ब्रेसिज़ निकालता है; समाधान एक तत्व के एक सेट के रूप में वापस किया गया था।


f[123456]

{३४ {, ४४, २०, ४}


3-PowerRepresentations

PowerRepresentations 4 वर्गों की समस्या के सभी समाधान लौटाता है। यह अन्य शक्तियों की रकम के लिए भी हल कर सकता है।

PowersRepresentations रिटर्न, 5 सेकंड के भीतर, 445 स्क्वॉयर के योग के रूप में 123456789 व्यक्त करने के 181 तरीके:

n= 123456;
PowersRepresentations[n, 4, 2] //AbsoluteTiming

Sols

हालाँकि, यह अन्य रकमों के लिए बहुत धीमी है।


वाह, गणितज्ञ तेज बल को तेज करता है। क्या IntegerPartitions हर संयोजन को आज़माने की तुलना में कुछ ज्यादा ही चालाक है, जैसे सेट पर DFT कनवल्शन? चश्मा संख्या के लिए पूछते हैं, वैसे, उनके वर्ग नहीं।
xnor

मुझे लगता है कि गणितज्ञ जानवर बल का उपयोग करता है, लेकिन शायद अनुकूलित किया है IntegerPartitions। जैसा कि आप समय से देख सकते हैं, यह गति इस बात पर निर्भर करती है कि पहली (सबसे बड़ी) संख्या वर्गमूल के करीब है या नहीं n। पहले संस्करण में कल्पना उल्लंघन को पकड़ने के लिए धन्यवाद।
डेविड

क्या आप बेंचमार्क कर सकते हैं f[805306368]? 4 पहले की शक्तियों से विभाजित किए बिना, मेरा समाधान 999999999 के लिए 0.05 एस लेता है; मैंने 5 मिनट के बाद 805306368 के लिए बेंचमार्क निरस्त कर दिया है ...
डेनिस

f[805306368]{16384, 16384, 16384}21 मिनट के बाद लौटता है । मैंने {4} के स्थान पर {3} का उपयोग किया। 4 गैर-शून्य वर्गों की राशि के साथ इसे हल करने का प्रयास कई घंटों की दौड़ के बाद असफल रहा।
डेविड

मेरे पास गणितज्ञ तक पहुंच नहीं है, लेकिन मैंने प्रलेखन केंद्र में जो पढ़ा है, उससे भी IntegerPartitions[n,4,Range[Floor@Sqrt@n]^2काम करना चाहिए। हालाँकि, मुझे नहीं लगता कि आपको अपने स्कोर के लिए विधि 1 का उपयोग करना चाहिए, क्योंकि यह प्रश्न में निर्दिष्ट समय सीमा का अनुपालन नहीं करता है।
डेनिस

7

पर्ल - 116 बाइट्स 87 बाइट्स (नीचे अपडेट देखें)

#!perl -p
$.<<=1,$_>>=2until$_&3;
{$n=$_;@a=map{$n-=$a*($a-=$_%($b=1|($a=0|sqrt$n)>>1));$_/=$b;$a*$.}($j++)x4;$n&&redo}
$_="@a"

शेबबैंग को एक बाइट के रूप में गिना, क्षैतिज पवित्रता के लिए नई कड़ियाँ जोड़ी गईं।

कुछ संयोजन सबमिशन।

औसत (सबसे खराब?) मामला जटिलता ओ (लॉग एन) ओ (एन 0.07 ) लगता है । कुछ भी नहीं मैंने 0.001 के मुकाबले धीमी गति से रन पाया है, और मैंने 900000000 - 999999999 से पूरी श्रृंखला की जाँच की है । यदि आपको ऐसा कुछ मिलता है, जो उससे अधिक समय लेता है, ~ 0.1 या अधिक, तो कृपया मुझे बताएं।


नमूना उपयोग

$ echo 123456789 | timeit perl four-squares.pl
11110 157 6 2

Elapsed Time:     0:00:00.000

$ echo 1879048192 | timeit perl four-squares.pl
32768 16384 16384 16384

Elapsed Time:     0:00:00.000

$ echo 999950883 | timeit perl four-squares.pl
31621 251 15 4

Elapsed Time:     0:00:00.000

इनमें से अंतिम दो अन्य सबमिशन के लिए सबसे बुरी स्थिति हैं। दोनों उदाहरणों में, दिखाया गया समाधान वास्तव में जाँच की गई पहली चीज़ है। के लिए 123456789, यह दूसरा है।

यदि आप मानों की श्रेणी का परीक्षण करना चाहते हैं, तो आप निम्न स्क्रिप्ट का उपयोग कर सकते हैं:

use Time::HiRes qw(time);

$t0 = time();

# enter a range, or comma separated list here
for (1..1000000) {
  $t1 = time();
  $initial = $_;
  $j = 0; $i = 1;
  $i<<=1,$_>>=2until$_&3;
  {$n=$_;@a=map{$n-=$a*($a-=$_%($b=1|($a=0|sqrt$n)>>1));$_/=$b;$a*$i}($j++)x4;$n&&redo}
  printf("%d: @a, %f\n", $initial, time()-$t1)
}
printf('total time: %f', time()-$t0);

सबसे अच्छा जब एक फ़ाइल के लिए पाइप। रेंज 1..1000000मेरे कंप्यूटर पर लगभग 14s लेता है (प्रति सेकंड 71000 मान), और सीमा O (लॉग एन) औसत जटिलता के 999000000..1000000000साथ संगत लगभग 20s (50000 मान प्रति सेकंड) लेता है।


अपडेट करें

संपादित करें : यह पता चलता है कि यह एल्गोरिदम एक के समान है जो कि मानसिक कैलकुलेटर द्वारा कम से कम एक सदी के लिए उपयोग किया गया है ।

मूल रूप से पोस्टिंग के बाद से, मैंने 1..1000000000 से सीमा पर हर मूल्य की जांच की है699731569 मूल्य द्वारा 'सबसे खराब स्थिति' व्यवहार का प्रदर्शन किया गया , जिसने एक समाधान पर पहुंचने से पहले 190 संयोजनों का एक शानदार परीक्षण किया । यदि आप 190 को एक छोटा स्थिरांक मानते हैं - और मैं निश्चित रूप से करता हूं - आवश्यक सीमा पर सबसे खराब मामला व्यवहार ओ (1) माना जा सकता है । यही कारण है कि, एक विशाल मेज से समाधान की तलाश में जितनी तेजी से, और औसतन, संभवतः काफी तेज है।

हालांकि एक और बात। 190 पुनरावृत्तियों के बाद , 144400 से बड़ा कुछ भी पहले पास से आगे नहीं बढ़ा । चौड़ाई-प्रथम ट्रैवर्सल के लिए तर्क बेकार है - इसका उपयोग भी नहीं किया जाता है। उपरोक्त कोड को थोड़ा छोटा किया जा सकता है:

#!perl -p
$.*=2,$_/=4until$_&3;
@a=map{$=-=$%*($%=$=**.5-$_);$%*$.}$j++,(0)x3while$=&&=$_;
$_="@a"

जो केवल खोज का पहला पास करता है। हमें इस बात की पुष्टि करने की आवश्यकता है कि 144400 से नीचे कोई मान नहीं है जिसे दूसरे पास की आवश्यकता थी, हालांकि:

for (1..144400) {
  $initial = $_;

  # reset defaults
  $.=1;$j=undef;$==60;

  $.*=2,$_/=4until$_&3;
  @a=map{$=-=$%*($%=$=**.5-$_);$%*$.}$j++,(0)x3while$=&&=$_;

  # make sure the answer is correct
  $t=0; $t+=$_*$_ for @a;
  $t == $initial or die("answer for $initial invalid: @a");
}

संक्षेप में, सीमा 1..1000000000 के लिए , एक निकट-स्थिर समय समाधान मौजूद है, और आप इसे देख रहे हैं।


अद्यतन अद्यतन

@ डेनिस और मैंने इस एल्गोरिथ्म में कई सुधार किए हैं। आप नीचे दी गई टिप्पणियों में प्रगति का पालन कर सकते हैं, और बाद में चर्चा कर सकते हैं, अगर वह आपकी रुचि रखता है। आवश्यक सीमा के लिए पुनरावृत्तियों की औसत संख्या केवल 4 से घटकर 1.229 हो गई है , और 1..1000000000 के लिए सभी मानों का परीक्षण करने के लिए आवश्यक समय 18m 54 से सुधर कर 2m 41s हो गया है। पहले सबसे खराब स्थिति में 190 पुनरावृत्तियों की आवश्यकता थी ; सबसे खराब स्थिति, अब 854382778 , केवल 21 की जरूरत है ।

अंतिम पायथन कोड निम्नलिखित है:

from math import sqrt

# the following two tables can, and should be pre-computed

qqr_144 = set([  0,   1,   2,   4,   5,   8,   9,  10,  13,
                16,  17,  18,  20,  25,  26,  29,  32,  34,
                36,  37,  40,  41,  45,  49,  50,  52,  53,
                56,  58,  61,  64,  65,  68,  72,  73,  74,
                77,  80,  81,  82,  85,  88,  89,  90,  97,
                98, 100, 101, 104, 106, 109, 112, 113, 116,
               117, 121, 122, 125, 128, 130, 133, 136, 137])

# 10kb, should fit entirely in L1 cache
Db = []
for r in range(72):
  S = bytearray(144)
  for n in range(144):
    c = r

    while True:
      v = n - c * c
      if v%144 in qqr_144: break
      if r - c >= 12: c = r; break
      c -= 1

    S[n] = r - c
  Db.append(S)

qr_720 = set([  0,   1,   4,   9,  16,  25,  36,  49,  64,  81, 100, 121,
              144, 145, 160, 169, 180, 196, 225, 241, 244, 256, 265, 289,
              304, 324, 340, 361, 369, 385, 400, 409, 436, 441, 481, 484,
              496, 505, 529, 544, 576, 580, 585, 601, 625, 640, 649, 676])

# 253kb, just barely fits in L2 of most modern processors
Dc = []
for r in range(360):
  S = bytearray(720)
  for n in range(720):
    c = r

    while True:
      v = n - c * c
      if v%720 in qr_720: break
      if r - c >= 48: c = r; break
      c -= 1

    S[n] = r - c
  Dc.append(S)

def four_squares(n):
  k = 1
  while not n&3:
    n >>= 2; k <<= 1

  odd = n&1
  n <<= odd

  a = int(sqrt(n))
  n -= a * a
  while True:
    b = int(sqrt(n))
    b -= Db[b%72][n%144]
    v = n - b * b
    c = int(sqrt(v))
    c -= Dc[c%360][v%720]
    if c >= 0:
      v -= c * c
      d = int(sqrt(v))

      if v == d * d: break

    n += (a<<1) - 1
    a -= 1

  if odd:
    if (a^b)&1:
      if (a^c)&1:
        b, c, d = d, b, c
      else:
        b, c = c, b

    a, b, c, d = (a+b)>>1, (a-b)>>1, (c+d)>>1, (c-d)>>1

  a *= k; b *= k; c *= k; d *= k

  return a, b, c, d

यह दो पूर्व-संकलित सुधार तालिकाओं का उपयोग करता है, आकार में एक 10kb, अन्य 253kb। उपरोक्त कोड में इन तालिकाओं के लिए जनरेटर फ़ंक्शन शामिल हैं, हालांकि इनका संकलन समय पर किया जाना चाहिए।

अधिक विनम्र आकार के सुधार तालिकाओं वाला एक संस्करण यहां पाया जा सकता है: http://codepad.org/1ebJC2OV इस संस्करण में प्रति टर्म औसतन 1.620 पुनरावृत्तियों की आवश्यकता होती है , जिसमें 38 का सबसे खराब मामला होता है , और पूरी रेंज लगभग 3 से 21 वर्ष में चलती है। बी केand लिए बिटवाइज़ का उपयोग करके, थोड़ा समय बनाया जाता हैमॉडुलो के बजाय करेक्शन के जाता है।


सुधार

यहां तक ​​कि मान भी विषम मानों की तुलना में एक समाधान का उत्पादन करने की अधिक संभावना रखते हैं।
मानसिक गणना लेख पहले के नोटों से जुड़ा हुआ है कि यदि, चार के सभी कारकों को हटाने के बाद, विघटित होने का मूल्य सम है, तो इस मान को दो से विभाजित किया जा सकता है, और समाधान का पुनर्निर्माण किया जा सकता है:

यद्यपि यह मानसिक गणना के लिए समझ में आता है (छोटे मानों को गणना करना आसान हो जाता है), यह एल्गोरिदमिक रूप से बहुत अर्थ नहीं देता है। यदि आप 256 रैंडम 4 -टुपल्स लेते हैं, और वर्गों के योग 8 की जांच करते हैं , तो आप पाएंगे कि मान 1 , 3 , 5 और 7 प्रत्येक औसत 32 बार पहुंच गए हैं । हालाँकि, मान 2 और 6 प्रत्येक 48 बार तक पहुँच चुके हैं। 2 से विषम मानों को गुणा करने पर, औसतन 33% कम पुनरावृत्तियों में एक समाधान मिलेगा । पुनर्निर्माण निम्नलिखित है:

देखभाल करने की आवश्यकता है कि और बी में समान समानता है, साथ ही साथ सी और डी भी है , लेकिन अगर कोई समाधान सभी में पाया गया, तो एक उचित आदेश मौजूद होने की गारंटी है।

असंभव रास्तों की जाँच करने की आवश्यकता नहीं है।
दूसरे मूल्य का चयन करने के बाद, बी , किसी समाधान के लिए पहले से ही असंभव हो सकता है, किसी भी दिए गए मोडो के लिए संभव द्विघात अवशेष। वैसे भी जाँच करने के बजाय, या अगली यात्रा पर जाने के बाद, b का मान छोटी मात्रा द्वारा इसे घटाकर 'सुधारा' जा सकता है जो संभवतः समाधान का कारण बन सकता है। दो सुधार तालिकाएँ इन मानों को संग्रहीत करती हैं, एक b के लिए और दूसरा c के लिए । उच्च मॉडुलो का उपयोग करना (अधिक सटीक रूप से, अपेक्षाकृत कम द्विघात अवशेषों के साथ मोडुलो का उपयोग करना) बेहतर परिणाम देगा। मूल्य एक किसी भी सुधार की जरूरत नहीं है; n को भी संशोधित करके , सभी मानों कोa वैध हैं।


1
यह अविश्वसनीय है! अंतिम एल्गोरिथ्म शायद सभी उत्तरों में से सबसे सरल है, फिर भी 190 पुनरावृत्तियां होती हैं ...
डेनिस

@ डेनिस मैं बहुत आश्चर्यचकित होता अगर इसका कहीं और उल्लेख नहीं किया गया होता। यह बहुत आसान लगता है अति-देखा गया है।
Primo

1. मैं उत्सुक हूं: क्या आपके जटिलता विश्लेषण में परीक्षण के किसी भी मूल्य को चौड़ाई-प्रथम ट्रावेल की आवश्यकता थी? 2. आप जिस विकिपीडिया लेख से जुड़े हैं वह थोड़ा भ्रमित करने वाला है। इसमें राबिन-श्लिट एल्गोरिथ्म का उल्लेख है, लेकिन एक पूरी तरह से अलग के लिए एक उदाहरण प्रदान करता है। 3. यह देखना दिलचस्प होगा कि वास्तव में राबिन-श्लिट अल्गोरिद्म आपका क्या नतीजा निकालेगा, मुझे लगता है कि व्यावहारिकता परीक्षण व्यावहारिक रूप से महंगे हैं।
डेनिस

1. कोई नहीं। 2. यह वह जगह है जहाँ मुझे मेरी जानकारी मिली (अर्थात यह एल्गोरिथ्म मौजूद है); मैंने विश्लेषण नहीं देखा है, या यहां तक ​​कि कागज भी पढ़ा है। 3. वक्र लगभग 1e60 पर इतना कठोर हो जाता है, कि यह वास्तव में कोई फर्क नहीं पड़ता कि O (log²n) कितना धीमा है, यह अभी भी उस बिंदु को पार करेगा।
Primo

1
प्रश्न में दूसरी कड़ी बताती है कि राबिन-शैलिट को कैसे लागू किया जाए, लेकिन यह जटिलता के बारे में बात नहीं करता है। MathOverflow पर यह उत्तर कागज का एक अच्छा सारांश देता है। वैसे, आपने 1911 ( लिंक ) में गॉटफ्रीड रूकल द्वारा उपयोग किए गए एल्गोरिथ्म को फिर से खोजा ।
डेनिस

6

पायथन 3 (177)

N=int(input())
k=1
while N%4<1:N//=4;k*=2
n=int(N**.5)
R=range(int(2*n**.5)+1)
print([(a*k,b*k,c*k,d*k)for d in R for c in R for b in R for a in[n,n-1]if a*a+b*b+c*c+d*d==N][0])

हम इनपुट Nको 4 से विभाज्य नहीं होने के बाद कम करते हैं , इसे चार वर्गों के योग के रूप में व्यक्त किया जाना चाहिए, जहां उनमें से एक या तो सबसे बड़ा संभव मूल्य है a=int(N**0.5)या उससे कम है, जो तीन अन्य वर्गों के योग के लिए केवल एक छोटा सा शेष है। देखभाल करना। यह खोज स्थान को बहुत कम कर देता है।

यहाँ एक प्रमाण है कि बाद में यह कोड हमेशा एक समाधान ढूंढता है। हम एक को खोजने के लिए चाहते हैं a, ताकि n-a^2तीन वर्गों का योग है। से लेगेंद्रे के तीन-स्क्वायर प्रमेय , एक नंबर तीन वर्गों का योग जब तक यह रूप है 4^j(8*k+7)। विशेष रूप से, ऐसी संख्याएं 0 या 3 (modulo 4) हैं।

हम दिखाने के कोई लगातार दो कि aबचे हुए राशि कर सकते हैं N-a^2लगातार दोनों मूल्यों के लिए इस तरह के एक आकार .. हम बस की एक तालिका बनाने के द्वारा ऐसा कर सकते हैं aऔर N4 सापेक्ष, यह देखते हुए कि N%4!=0क्योंकि हम में से 4 की सभी शक्तियों निकाला है N

  a%4= 0123
      +----
     1|1010
N%4= 2|2121  <- (N-a*a)%4
     3|3232

क्योंकि कोई भी लगातार दो नहीं aदेता है (N-a*a)%4 in [0,3], उनमें से एक का उपयोग करना सुरक्षित है। इसलिए, हम लालच के nसाथ सबसे बड़ा संभव उपयोग करते हैं n^2<=N, और n-1। चूंकि N<(n+1)^2, शेष N-a^2को तीन वर्गों के योग के रूप में दर्शाया गया है (n+1)^2 -(n-1)^2, जो कि बराबर है 4*n। तो, यह केवल मानों की जांच करने के लिए पर्याप्त है 2*sqrt(n), जो कि वास्तव में सीमा है R

एक एकल समाधान के बाद रुककर, अंतिम मान के लिए पुनरावृत्ति करने के बजाय कंप्यूटिंग d, और केवल मूल्यों के बीच खोज करके आगे चल रहे समय को अनुकूलित किया जा सकता है b<=c<=d। लेकिन, इन अनुकूलन के बिना भी, सबसे खराब उदाहरण मैं अपनी मशीन पर 45 सेकंड में समाप्त हो सकता है।

"एक्स फॉर आर में" की श्रृंखला दुर्भाग्यपूर्ण है। यह शायद स्ट्रिंग प्रतिस्थापन या एक एकल सूचकांक पर पुनरावृत्ति करके प्रतिस्थापन द्वारा छोटा किया जा सकता है जो एन्कोड करता है (ए, बी, सी, डी)। आयात करने वाले इटर्टूल इसके लायक नहीं थे।

संपादित करें: तर्क क्लीनर, एक ही वर्ण गणना बनाने के लिए int(2*n**.5)+1से बदला गया 2*int(n**.5)+2


यह मेरे लिए काम नहीं करता ...5 => (2, 1, 0, 0)
हैरी बीडल

अजीब बात है, यह मेरे लिए काम करता है: मैं 5 => (2, 1, 0, 0)Ideone 3.2.3 या Idle 3.2.2 पर चल रहा हूं । आपको क्या मिलेगा?
xnor

1
@xnor BritishColour हो जाता है 5 => (2, 1, 0, 0)। क्या आपने टिप्पणी भी पढ़ी? (अब हमारे पास एक पंक्ति में 3 टिप्पणियां हैं, जिसमें वह कोड स्निपेट है। क्या हम लकीर को रख सकते हैं?)
जस्टिन

@Quincunx अगर हम समझाना चाहते हैं 5 => (2, 1, 0, 0), तो इसका मतलब है 2^2 + 1^2 + 0^2 + 0^2 = 5। तो, हाँ, हम कर सकते हैं।
डॉ। रेम्बु

1
Quincunx, मैंने @ BritishColour की टिप्पणी पढ़ी, और जहाँ तक मैं देख सकता हूँ, 5 => (2, 1, 0, 0)सही है। प्रश्न में दिए गए उदाहरण 0 ^ 2 = 0 को एक मान्य वर्ग संख्या मानते हैं। इसलिए मैंने व्याख्या की (जैसा कि मुझे लगता है कि xnor ने किया था) कि ब्रिटिश कलर को कुछ और मिला है। ब्रिटिश रंग, जैसा कि आपने फिर से जवाब नहीं दिया, क्या हम मान सकते हैं कि आप वास्तव में प्राप्त करते हैं 2,1,0,0?
लेवल रिवर सेंट

5

CJam , 91 90 74 71 बाइट्स

q~{W):W;:N4md!}gmqi257:B_**_{;)_[Bmd\Bmd]_N\{_*-}/mq_i@+\1%}g{2W#*}%`\;

मेरे अन्य दृष्टिकोण की तुलना में कॉम्पैक्ट, लेकिन धीमी।

इसे ऑनलाइन आज़माएं! कोड पेस्ट करें , इनपुट में वांछित पूर्णांक टाइप करें और रन पर क्लिक करें ।

पृष्ठभूमि

यह पोस्ट 99 बाइट गोल्फस्क्रिप्ट उत्तर के रूप में शुरू हुई । जबकि सुधार के लिए अभी भी जगह नहीं थी, GolfScript में अंतर्निहित sqrt फ़ंक्शन का अभाव है। मैंने 5 तक संशोधन के लिए GolfScript संस्करण रखा , क्योंकि यह CJam संस्करण के समान था।

हालांकि, संशोधन 6 के बाद से अनुकूलन की आवश्यकता होती है, जो ऑपरेटरों को गोल्फस्क्रिप्ट में उपलब्ध नहीं हैं, इसलिए दोनों भाषाओं के लिए अलग-अलग स्पष्टीकरण पोस्ट करने के बजाय, मैंने कम प्रतिस्पर्धी (और बहुत धीमी) संस्करण को छोड़ने का फैसला किया।

कार्यान्वित एल्गोरिथ्म ब्रूट बल द्वारा संख्याओं की गणना करता है:

  1. इनपुट के लिए m, ढूंढें Nऔर Wऐसे m = 4**W * N

  2. सेट करें i = 257**2 * floor(sqrt(N/4))

  3. सेट करें i = i + 1

  4. पूर्णांकों को j, k, lऐसे खोजें i = 257**2 * j + 257 * k + l, जहां k, l < 257

  5. जाँच करें कि d = N - j**2 - k**2 - l**2क्या एक पूर्ण वर्ग है।

  6. यदि यह नहीं है, और चरण 3 पर वापस जाएं।

  7. प्रिंट करें 2**W * j, 2**W * k, 2**W * l, 2**W * sqrt(m)

उदाहरण

$ TIME='\n%e s' time cjam lagrange.cjam <<< 999999999
[27385 103 15813 14]
0.46 s
$ TIME='\n%e s' time cjam lagrange.cjam <<< 805306368
[16384 16384 0 16384]
0.23 s

समय एक इंटेल कोर i7-4700MQ के अनुरूप है।

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

q~              " Read and interpret the input. ";
{
  W):W;         " Increment “W” (initially -1). ";
  :N            " Save the integer on the stack in “N”. ';
  4md!          " Push N / 4 and !(N % 4). ";
}g              " If N / 4 is an integer, repeat the loop.
mqi             " Compute floor(sqrt(N/4)). ";
257:B_**        " Compute i = floor(sqrt(N)) * 257**2. ";
_               " Duplicate “i” (dummy value). ";
{               " ";
  ;)_           " Pop and discard. Increment “i”. ";
  [Bmd\Bmd]     " Push [ j k l ], where i = 257**2 * j + 257 * k + l and k, l < 257. ";
  _N\           " Push “N” and swap it with a copy of [ j k l ]. ";
  {_*-}/        " Compute m = N - j**2 - k**2 - l**2. ";
  mq            " Compute sqrt(m). ";
  _i            " Duplicate sqrt(m) and compute floor(sqrt(m)). ";
  @+\           " Form [ j k l floor(sqrt(m)) ] and swap it with sqrt(m). ";
  1%            " Check if sqrt(m) is an integer. ";
}g              " If it is, we have a solution; break the loop. ";
{2W#*}%         " Push 2**W * [ j k l sqrt(m) ]. ";
`\;             " Convert the array into a string and discard “i”. ";

2

सी, 228

यह विकिपीडिया पृष्ठ पर एल्गोरिथ्म पर आधारित है, जो एक ओ (एन) जानवर-बल है।

n,*l,x,y,i;main(){scanf("%d",&n);l=calloc(n+1,8);
for(x=0;2*x*x<=n;x++)for(y=x;(i=x*x+y*y)<=n;y++)l[2*i]=x,l[2*i+1]=y;
for(x=0,y=n;;x++,y--)if(!x|l[2*x+1]&&l[2*y+1]){
printf("%d %d %d %d\n",l[2*x],l[2*x+1],l[2*y],l[2*y+1]);break;}}

2

गोल्फस्क्रिप्ट, 133 130 129 बाइट्स

~{.[4*{4/..4%1$!|!}do])\}:r~,(2\?:f;{{..*}:^~4-1??n*,}:v~)..
{;;(.^3$\-r;)8%!}do-1...{;;;)..252/@252%^@^@+4$\-v^@-}do 5$]{f*}%-4>`

तेज, लेकिन लंबा। नई लाइन को हटाया जा सकता है।

इसे ऑनलाइन आज़माएं।ध्यान दें कि ऑनलाइन दुभाषिया की समय सीमा 5 सेकंड है, इसलिए यह सभी नंबरों के लिए काम नहीं कर सकता है।

पृष्ठभूमि

एल्गोरिथ्म लीजेंड्रे के तीन-वर्ग प्रमेय का लाभ उठाता है , जो बताता है कि प्रत्येक प्राकृतिक संख्या n जो कि फॉर्म का नहीं है

                                                                   n = 4 ** a * (8b + 7)

तीन के योग के रूप में व्यक्त किया जा सकता है वर्गों है।

एल्गोरिथ्म निम्नलिखित करता है:

  1. के रूप में संख्या व्यक्त करें 4**i * j

  2. kइस तरह के सबसे बड़े पूर्णांक का पता लगाएं k**2 <= jऔर j - k**2लीजेंड्रे के तीन-वर्ग प्रमेय की परिकल्पना को संतुष्ट करता है।

  3. सेट करें i = 0

  4. जाँच करें कि j - k**2 - (i / 252)**2 - (i % 252)**2क्या एक पूर्ण वर्ग है।

  5. यदि यह नहीं है, तो वेतन वृद्धि iऔर चरण 4 पर वापस जाएं।

उदाहरण

$ TIME='%e s' time golfscript legendre.gs <<< 0
[0 0 0 0]
0.02 s
$ TIME='%e s' time golfscript legendre.gs <<< 123456789
[32 0 38 11111]
0.02 s
$ TIME='%e s' time golfscript legendre.gs <<< 999999999
[45 1 217 31622]
0.03 s
$ TIME='%e s' time golfscript legendre.gs <<< 805306368
[16384 0 16384 16384]
0.02 s

समय एक इंटेल कोर i7-4700MQ के अनुरूप है।

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

~              # Interpret the input string. Result: “n”
{              #
  .            # Duplicate the topmost stack item.
  [            #
    4*         # Multiply it by four.
    {          #
      4/       # Divide by four.
      ..       # Duplicate twice.
      4%1$     # Compute the modulus and duplicate the number.
      !|!      # Push 1 if both are truthy.
    }do        # Repeat if the number is divisible by four and non-zero.
  ]            # Collect the pushed values (one per iteration) into an array.
  )\           # Pop the last element from the array and swap it with the array.
}:r~           # Save this code block as “r” and execute it.
,(2\?          # Get the length of the array, decrement it and exponentiate.
:f;            # Save the result in “f”.
               # The topmost item on the stack is now “j”, which is not divisible by 
               # four and satisfies that n = f**2 * j.
{              #
  {..*}:^~     # Save a code block to square a number in “^” and execute it.
  4-1??        # Raise the previous number to the power of 1/4.
               # The two previous lines compute (x**2)**(1/4), which is sqrt(abs(x)).
  n*,          # Repeat the string "\n" that many times and compute its length.
               # This casts to integer. (GolfScript doesn't officially support Rationals.)
}:v~           # Save the above code block in “v” and execute it.
)..            # Undo the first three instructions of the loop.
{              #
   ;;(         # Discard two items from the stack and decrement.
   .^3$\-      # Square and subtract from “n”.
   r;)8%!      # Check if the result satisfies the hypothesis of the three-square theorem.
}do            # If it doesn't, repeat the loop.
-1...          # Push 0 (“i”) and undo the first four instructions of the loop.
{              #
  ;;;)         # Discard two items from the stack and increment “i”.
  ..252/@252%  # Push the digits of “i” in base 252.
  ^@^@+4$\-    # Square both, add and subtract the result 
  v^@-         # Take square root, square and compare.
}do            # If the difference is a perfect square, break the loop.
5$]            # Duplicate the difference an collect the entire stack into an array.
{f*}%          # Multiply very element of the array by “f”.
-4>            # Reduce the array to its four last elements (the four numbers).
`              # Convert the result into a string.

1
मुझे समझ नहीं आया j-k-(i/252)-(i%252)। आपकी टिप्पणियों से (मैं वास्तव में कोड नहीं पढ़ सकता), ऐसा लगता है कि आप का मतलब है j-k-(i/252)^2-(i%252)^2। BTW, j-k-(i/r)^2-(i%r)^2जहाँ r = sqrt (k) के समतुल्य कुछ वर्णों को बचा सकता है (और मेरे C प्रोग्राम में k = 0 के लिए भी समस्याओं के बिना काम करता है।)
लेवल रिवर सेंट

@steveverrill: हां, मैंने गलती की। ध्यान देने के लिए धन्यवाद। यह होना चाहिए j-k^2-(i/252)^2-(i%252)^2। मैं अभी भी ओपी को स्पष्ट करने के लिए इंतजार कर रहा हूं कि क्या 0 एक वैध इनपुट है या नहीं। आपका कार्यक्रम 1414 -nan 6 4.000000इनपुट के लिए देता है 0
डेनिस

मैं लेजेंड्रे के प्रमेय का उपयोग करके अपने नए कार्यक्रम के बारे में बात कर रहा हूं, जिसे मैंने अभी तक पोस्ट नहीं किया है। ऐसा लगता है कि यह कभी भी कोड को% या / जब मेरे पास k = 0 के बराबर नहीं है, यही कारण है कि यह समस्या पैदा नहीं कर रहा है। जब मैं इसे पोस्ट करूँगा तो आप देखेंगे। खुशी है कि आपको मेरा पुराना कार्यक्रम चल रहा है। क्या आपके पास Rev 2 में पूर्ण 2GB तालिका बनाने की मेमोरी है, और इसमें कितना समय लगा?
लेवल रिवर सेंट

हाँ, सी कंपाइलर अनुकूलन करते समय काफी अप्रत्याशित रूप से व्यवहार कर सकता है। GolfScript में, 0/=> क्रैश! : P मैंने अपने लैपटॉप (i7-4700MQ, 8 GiB RAM) पर अपना Rev 1 चलाया है। औसतन, निष्पादन का समय 18.5 सेकंड है।
डेनिस

वाह क्या मेज बनाने सहित 18.5 सेकंड है? मेरी मशीन पर 2 मिनट लगते हैं। मैं देख सकता हूँ कि समस्या विंडोज मेमोरी मैनेजमेंट है। कार्यक्रम को सीधे 2GB की जरूरत है, इसे देने के बजाय, यह इसे छोटे खंडों में देता है, इसलिए जब तक पूरा 2GB आवंटित नहीं किया जाता है, तब तक इसे बहुत अधिक अनावश्यक स्वैपिंग करना होगा। वास्तव में प्रति उपयोगकर्ता इनपुट के जवाब की खोज बहुत तेज है, क्योंकि तब तक प्रोग्राम को मेमोरी के लिए भीख नहीं मांगनी पड़ती है।
लेवल रिवर सेंट

1

Rev 1: C, 190

a,z,m;short s[15<<26];p(){m=s[a=z-a];printf("%d %f ",m,sqrt(a-m*m));}
main(){m=31727;for(a=m*m;--a;s[z<m*m?z:m*m]=a%m)z=a/m*(a/m)+a%m*(a%m);scanf("%d",&z);for(;a*!s[a]||!s[z-a];a++);p();p();}

यह 0. 0. रीव्यू से अधिक मेमोरी वाला भूखा है। समान सिद्धांत: 2 वर्गों (और उन संख्याओं के लिए शून्य जो दो वर्गों के योग नहीं हैं) के लिए एक सकारात्मक मान के साथ एक तालिका बनाएं, फिर इसे खोजें।

इस रिवॉर्ड में हिट्स को स्टोर करने के shortबजाय एक ऐरे का उपयोग करें char, इसलिए मैं सिर्फ एक झंडे के बजाय टेबल में जोड़े वर्गों में से एक की जड़ को स्टोर कर सकता हूं। यह फ़ंक्शन को सरल करता है p(2 वर्गों के योग को डिकोड करने के लिए) काफी है क्योंकि लूप की कोई आवश्यकता नहीं है।

विंडोज़ में सरणियों पर 2GB की सीमा है। मैं उस राउंड को प्राप्त कर सकता हूं short s[15<<26]जिसके साथ 1006632960 तत्वों की एक सरणी है, जो कल्पना का अनुपालन करने के लिए पर्याप्त है। दुर्भाग्य से, कुल प्रोग्राम रनटाइम आकार अभी भी 2GB से अधिक है और (OS सेटिंग्स को short s[14<<26]ट्विक करने के बावजूद) मैं इस आकार से अधिक नहीं चला पा रहा हूं (हालांकि यह सैद्धांतिक रूप से संभव है।) सबसे अच्छा मैं कर सकता हूं (939524096 तत्व।)m*m होना चाहिए इससे सख्ती से कम (30651 ^ 2 = 939483801)। फिर भी, कार्यक्रम पूरी तरह से चलता है और किसी भी ओएस पर काम करना चाहिए जिसमें यह प्रतिबंध नहीं है।

अघोषित कोड

a,z,m;
short s[15<<26];     
p(){m=s[a=z-a];printf("%d %f ",m,sqrt(a-m*m));}      
main(){       
 m=31727;             
 for(a=m*m;--a;s[z<m*m?z:m*m]=a%m)   //assignment to s[] moved inside for() is executed after the following statement. In this rev excessively large values are thrown away to s[m*m].
   z=a/m*(a/m)+a%m*(a%m);            //split a into high and low half, calculate h^2+l^2.                                  
 scanf("%d",&z); 
 for(;a*!s[a]||!s[z-a];a++);         //loop until s[a] and s[z-a] both contain an entry. s[0] requires special handling as s[0]==0, therefore a* is included to break out of the loop when a=0 and s[z] contains the sum of 2 squares.
 p();                                //print the squares for the first sum of 2 squares 
 p();}                               //print the squares for the 2nd sum of 2 squares (every time p() is called it does a=z-a so the two sums are exchanged.) 

रेव 0 सी, 219

a,z,i,m;double t;char s[1<<30];p(){for(i=t=.1;(m=t)-t;i++)t=sqrt(a-i*i);printf("%d %f ",i-1,t);}
main(){m=1<<15;for(a=m*m;--a;){z=a/m*(a/m)+a%m*(a%m);s[z<m*m?z:0]=1;}scanf("%d",&z);for(;1-s[a]*s[z-a];a++);p();a=z-a;p();}

यह एक मेमोरी वाला भूखा जानवर है। यह 1GB सरणी लेता है, 2 वर्गों के सभी संभावित योगों की गणना करता है और सरणी में प्रत्येक के लिए एक ध्वज संग्रहीत करता है। फिर उपयोगकर्ता इनपुट z के लिए, यह 2 वर्गों के लिए दो वर्गों और za के लिए सरणी खोजता है।

समारोह pतो मूल वर्गों है कि 2 वर्गों की रकम बनाने के लिए इस्तेमाल किया गया reconsitutes aऔर z-aएक पूर्णांक के रूप में प्रत्येक जोड़ी के पहले और उन्हें प्रिंट, एक डबल के रूप में दूसरा (अगर यह है सभी पूर्णांकों दो और पात्रों की जरूरत है हो सकता है, t> m=t)

कार्यक्रम कुछ मिनटों के वर्गों के निर्माण के लिए कुछ मिनट लगते हैं (मुझे लगता है कि यह स्मृति प्रबंधन के मुद्दों के कारण है, मुझे लगता है कि स्मृति आवंटन धीरे-धीरे ऊपर जा रहा है क्योंकि कोई उम्मीद नहीं कर सकता है।) हालांकि एक बार ऐसा किया जाता है। बहुत जल्दी जवाब देता है (यदि कई संख्याओं की गणना की जानी है, तो scanfआगे से प्रोग्राम को लूप में रखा जा सकता है।

असमतल कोड

a,z,i,m;
double t;
char s[1<<30];                              //handle numbers 0 up to 1073741823
p(){
 for(i=t=.1;(m=t)-t;i++)t=sqrt(a-i*i);      //where a contains the sum of 2 squares, search until the roots are found
 printf("%d %f ",i-1,t);}                   //and print them. m=t is used to evaluate the integer part of t. 

main(){       
 m=1<<15;                                   //max root we need is sqrt(1<<30);
 for(a=m*m;--a;)                            //loop m*m-1 down to 1, leave 0 in a
   {z=a/m*(a/m)+a%m*(a%m);s[z<m*m?z:0]=1;}  //split a into high and low half, calculate h^2+l^2. If under m*m, store flag, otherwise throw away flag to s[0]
 scanf("%d",&z);
 for(;1-s[a]*s[z-a];a++);                   //starting at a=0 (see above) loop until flags are found for sum of 2 squares of both (a) and (z-a)
 p();                                       //reconsitute and print the squares composing (a)
 a=z-a;                                     //assign (z-a) to a in order to...
 p();}                                      //reconsitute and print the squares composing (z-a)  

उदाहरण आउटपुट

पहला सवाल के अनुसार है। दूसरे को खोजने के लिए मुश्किल के रूप में चुना गया था। इस मामले में कार्यक्रम को 8192 ^ 2 + 8192 ^ 2 = 134217728 तक खोजना है, लेकिन तालिका बनने के बाद कुछ ही सेकंड लगते हैं।

123456789
0 2.000000 3328 10601.000000

805306368
8192 8192.000000 8192 24576.000000

क्या आपको sqrt के लिए एक प्रोटोटाइप नहीं जोड़ना चाहिए?
edc65

@ edc65 मैं GCC कंपाइलर का उपयोग कर रहा हूं (जो कि लिनक्स के लिए है, लेकिन मेरे विंडोज मशीन पर साइग्विन लिनक्स वातावरण स्थापित है।) इसका मतलब है कि मुझे #include <stdio.h>(स्कैनफ / प्रिंटफ के लिए) या #include <math.h>(sqrt के लिए) कंपाइलर की आवश्यकता नहीं है। आवश्यक पुस्तकालयों को स्वचालित रूप से लिंक करता है। मुझे इसके लिए डेनिस का शुक्रिया अदा करना है (उन्होंने मुझसे इस सवाल पर कहा था codegolf.stackexchange.com/a/26330/15599 ) बेस्ट गोल्फ टिप जो मेरे पास कभी थी।
लेवल रिवर सेंट

मैं पहले से ही सोच रहा था कि हंट द वम्पस जुड़े सवालों में क्यों दिखाई दिए। :) वैसे, मुझे नहीं पता है कि विंडोज पर जीसीसी क्या उपयोग करता है, लेकिन जीएनयू लिंकर गणित पुस्तकालय को स्वचालित रूप से लिंक नहीं करता है, इसके साथ या बिना include। लिनक्स पर संकलन करने के लिए, आपको ध्वज की आवश्यकता है-lm
डेनिस

@Dennis कि दिलचस्प है, यह शामिल नहीं stdioकई अन्य पुस्तकालयों, लेकिन नहीं और mathभी साथinclude ? जिससे मैं समझता हूँ कि यदि आप संकलक ध्वज लगाते हैं, तो आपको किसी includeभी तरह की आवश्यकता नहीं है? वैसे यह मेरे लिए काम कर रहा है, इसलिए मैं शिकायत नहीं कर रहा हूं, फिर से टिप के लिए धन्यवाद। बीटीडब्ल्यू मैं लीजेंड्रे की प्रमेय का लाभ उठाते हुए एक पूरी तरह से अलग उत्तर पोस्ट करने की उम्मीद कर रहा हूं (लेकिन यह अभी भी एक का उपयोग करेगा sqrt।)
स्तर नदी सेंट

-lmलिंकर को प्रभावित करता है, संकलक को नहीं। gccऑप्स को "यह" पता है कि फ़ंक्शन के लिए प्रोटोटाइप की आवश्यकता नहीं है, इसलिए यह शामिल के साथ या इसके बिना काम करता है। हालाँकि, शीर्ष लेख केवल कार्य करता है, फ़ंक्शन नहीं करता है। लिनक्स पर (लेकिन विंडोज नहीं, जाहिरा तौर पर), गणित लाइब्रेरी लिब्रम मानक पुस्तकालयों का हिस्सा नहीं है, इसलिए आपको ldइसे लिंक करने का निर्देश देना होगा।
डेनिस

1

गणितज्ञ, १३ 138 वर्ण

तो यह पता चला है कि यह edc65 (उदाहरण के लिए, 805306368) द्वारा इंगित किए गए कुछ इनपुटों के लिए नकारात्मक और काल्पनिक परिणाम उत्पन्न करता है, इसलिए यह एक वैध समाधान नहीं है। मैं इसे अभी के लिए छोड़ दूंगा, और हो सकता है, अगर मैं वास्तव में अपने समय से नफरत करता हूं, तो मैं वापस जाऊंगा और इसे ठीक करने की कोशिश करूंगा।

S[n_]:=Module[{a,b,c,d},G=Floor@Sqrt@#&;a=G@n;b:=G[n-a^2];c:=G[n-a^2-b^2];d:=G[n-a^2-b^2-c^2];While[Total[{a,b,c,d}^2]!=n,a-=1];{a,b,c,d}]

या, असुरक्षित:

S[n_] := Module[{a, b, c, d}, G = Floor@Sqrt@# &;
 a = G@n;
 b := G[n - a^2];
 c := G[n - a^2 - b^2];
 d := G[n - a^2 - b^2 - c^2];
 While[Total[{a, b, c, d}^2] != n, a -= 1];
 {a, b, c, d}
]

मैं एल्गोरिदम में बहुत मुश्किल नहीं दिख रहा था, लेकिन मुझे उम्मीद है कि यह एक ही विचार है। मैं सिर्फ स्पष्ट समाधान के साथ आया और इसे तब तक काम किया जब तक यह काम नहीं किया। मैंने इसे 1 से एक बिलियन के बीच सभी संख्याओं के लिए परीक्षण किया और ... यह काम करता है। मेरी मशीन पर परीक्षण में केवल 100 सेकंड लगते हैं।

इसके बारे में अच्छा सा यह है कि, चूंकि b, c, और d को विलंबित असाइनमेंट के साथ परिभाषित किया गया है :=, इसलिए जब उन्हें डीरिक्वायर्ड किया जाता है, तो उन्हें फिर से परिभाषित नहीं करना पड़ेगा। इससे पहले मेरे पास मौजूद कुछ अतिरिक्त लाइनें बच गईं। मैं इसे और आगे बढ़ा सकता हूं और निरर्थक भागों को घोंसला बना सकता हूं, लेकिन यहां पहला मसौदा है।

ओह, और आप इसे चलाते हैं S@123456789और आप इसके साथ परीक्षण कर सकते हैं {S@#, Total[(S@#)^2]} & @ 123456789या # == Total[(S@#)^2]&[123456789]। एग्जॉस्ट टेस्ट है

n=0;
AbsoluteTiming@ParallelDo[If[e != Total[(S@e)^2], n=e; Abort[]] &, {e, 1, 1000000000}]
n

मैंने पहले एक प्रिंट [] स्टेटमेंट का उपयोग किया था लेकिन इसने इसे बहुत धीमा कर दिया, भले ही इसे कभी भी कॉल न किया जाए। जाओ पता लगाओ।


यह वास्तव में साफ है! मुझे आश्चर्य है कि यह केवल हर मूल्य लेने के लिए पर्याप्त है, लेकिन जितना संभव हो उतना पहला। गोल्फिंग के लिए, शायद यह n - a^2 - b^2 - c^2एक चर के रूप में सहेजने और d^2इसे बराबर करने वाली जांच करने के लिए कम है।
xnor

2
क्या यह वास्तव में काम करता है? 805306368 इनपुट के लिए क्या समाधान खोजता है?
edc65

S [805306368] = {- 28383, 536 I, 32 I, I}। हुह। यही कारण है कि करता है 805306368 पैदा करता है जब आप इसे योग, लेकिन स्पष्ट रूप से इस एल्गोरिथ्म के साथ एक समस्या है। मुझे लगता है कि मुझे इसे अभी के लिए वापस लेना होगा; यह इंगित करने के लिए धन्यवाद ...
krs013

2
संख्या जो सभी को विफल करती है, वे 2 की बड़ी शक्तियों से विभाज्य प्रतीत होती हैं। विशेष रूप से, वे 4 की सभी शक्तियों को बाहर निकालने के a * 4^(2^k)लिए फार्म के प्रतीत होते हैं k>=2, ताकिa एक से अधिक नहीं है (लेकिन यह भी हो सकता है)। इसके अलावा, प्रत्येक aया तो 3 mod 4 है, या दो बार ऐसी संख्या है। सबसे छोटा एक 192 है।
xnor

1

हास्केल 123 + 3 = 126

main=getLine>>=print.f.read
f n=head[map(floor.sqrt)[a,b,c,d]|a<-r,b<-r,c<-r,d<-r,a+b+c+d==n]where r=[x^2|x<-[0..n],n>=x^2]

पूर्व-गणना वाले वर्गों पर सरल जानवर बल।

इसे -Oसंकलन विकल्प की आवश्यकता है (मैंने इसके लिए 3 वर्ण जोड़े)। सबसे खराब स्थिति 999950883 के लिए 1 मिनट से भी कम समय लगता है।

केवल जीएचसी पर परीक्षण किया गया।


1

C: 198 वर्ण

मैं शायद इसे सिर्फ 100 से अधिक पात्रों तक निचोड़ सकता हूं। इस समाधान के बारे में मुझे जो पसंद है वह है कबाड़ की न्यूनतम मात्रा, बस एक सादा-लूप, यह करने के लिए कि एक लूप को क्या करना चाहिए (जो कि पागल होना है)।

i,a,b,c,d;main(n){for(scanf("%d",&n);a*a+b*b-n?a|!b?a*a>n|a<b?(--a,b=1):b?++b:++a:(a=b=0,--n,++i):c*c+d*d-i?c|!d?c*c>i|c<d?(--c,d=1):d?++d:++c:(a=b=c=d=0,--n,++i):0;);printf("%d %d %d %d",a,b,c,d);}

और भारी पूर्वनिर्धारित:

#include <stdio.h>

int n, i, a, b, c, d;

int main() {
    for (
        scanf("%d", &n);
        a*a + b*b - n
            ? a | !b
                ? a*a > n | a < b
                    ? (--a, b = 1)
                    : b
                        ? ++b
                        : ++a
                : (a = b = 0, --n, ++i)
            : c*c + d*d - i
                ? c | !d
                    ? c*c > i | c < d
                        ? (--c, d = 1)
                        : d
                            ? ++d
                            : ++c
                    : (a = b = c = d = 0, --n, ++i)
                : 0;
    );
    printf("%d %d %d %d\n", a, b, c, d);
    return 0;
}

संपादित करें: यह सभी इनपुट के लिए पर्याप्त तेज़ नहीं है, लेकिन मैं दूसरे समाधान के साथ वापस आऊंगा। मैं इस टर्नरी ऑपरेशन मेस को अभी रहने दूंगा।


1

रेव बी: सी, 179

a,b,c,d,m=1,n,q,r;main(){for(scanf("%d",&n);n%4<1;n/=4)m*=2;
for(a=sqrt(n),a-=(3+n-a*a)%4/2;r=n-a*a-b*b-c*c,d=sqrt(r),d*d-r;c=q%256)b=++q>>8;
printf("%d %d %d %d",a*m,b*m,c*m,d*m);}

@ डेनिस को सुधार के लिए धन्यवाद। नीचे दिए गए शेष उत्तर को संशोधित ए से अपडेट नहीं किया गया है।

रेव ए: सी, 195

a,b,c,d,n,m,q;double r=.1;main(){scanf("%d",&n);for(m=1;!(n%4);n/=4)m*=2;a=sqrt(n);a-=(3+n-a*a)%4/2;
for(;(d=r)-r;q++){b=q>>8;c=q%256;r=sqrt(n-a*a-b*b-c*c);}printf("%d %d %d %d ",a*m,b*m,c*m,d*m);}

मेरे अन्य उत्तर की तुलना में बहुत तेज और बहुत कम स्मृति के साथ!

यह http://en.wikipedia.org/wiki/Legendre%27s_three-square_theorem का उपयोग करता है । निम्नलिखित फॉर्म की कोई संख्या 3 वर्गों के योग के रूप में व्यक्त की जा सकती है (मैं इसे निषिद्ध रूप कहता हूं):

4^a*(8b+7), or equivalently 4^a*(8b-1)

ध्यान दें कि सभी विषम वर्ग संख्याएँ फॉर्म की हैं (8b+1)और सभी वर्ग संख्याएँ रूप के सतही रूप से हैं 4b। हालांकि यह इस तथ्य को छिपाता है कि सभी वर्ग संख्याएं फॉर्म की हैं 4^a*(odd square)==4^a*(8b+1)। नतीजतन2^x-(any square number < 2^(x-1)) विषम के xलिए हमेशा निषिद्ध रूप होगा। इसलिए ये संख्याएँ और उनके गुणक कठिन मामले हैं, यही वजह है कि यहाँ कई कार्यक्रम पहले चरण के रूप में 4 की शक्तियों को विभाजित करते हैं।

जैसा कि @ xnor के उत्तर में कहा गया है, N-a*a के 2 लगातार मूल्यों के लिए निषिद्ध रूप नहीं हो सकता है a। नीचे मैं उनकी तालिका का एक सरलीकृत रूप प्रस्तुत करता हूँ। इस तथ्य के अलावा कि 4 के बाद विभाजन N%40 के बराबर नहीं हो सकता है, ध्यान दें कि इसके लिए केवल 2 संभावित मान हैं (a*a)%4

(a*a)%4= 01
        +--
       1|10
  N%4= 2|21  <- (N-a*a)%4
       3|32

इसलिए, हम उन मूल्यों से बचना चाहते हैं (N-a*a)जो निषिद्ध रूप से हो सकते हैं, अर्थात् जहां (N-a*a)%43 या 0. है , वहां देखा जा सकता है कि यह Nविषम और समान दोनों के लिए समान नहीं हो सकता है।(a*a)

तो, मेरा एल्गोरिथ्म इस तरह काम करता है:

1. Divide out powers of 4
2. Set a=int(sqrt(N)), the largest possible square
3. If (N-a*a)%4= 0 or 3, decrement a (only once)
4. Search for b and c such that N-a*a-b*b-c*c is a perfect square

मैं विशेष रूप से जिस तरह से मैं चरण 3 करता हूं। मैं 3 को जोड़ता हूं N , ताकि अगर आवश्यक हो तो वेतन वृद्धि हो(3+N-a*a)%4 = 3 या 2 ( 1 या 0. नहीं) इसे 2 से विभाजित करें और पूरे काम को काफी सरल अभिव्यक्ति द्वारा किया जा सकता है ।

अघोषित कोड

एकल नोट forपाश qऔर विभाजन / सापेक्ष के उपयोग के मूल्यों को प्राप्त करने के bलिए और cइसे से। मैंने aबाइट को बचाने के लिए 256 के बजाय एक डिविज़र के रूप में उपयोग करने की कोशिश की , लेकिन कभी-कभी मूल्य aसही नहीं था और कार्यक्रम लटका दिया, संभवतः अनिश्चित काल तक। 256 सबसे अच्छा समझौता था जैसा कि मैं विभाजन >>8के /256लिए उपयोग कर सकता हूं ।

a,b,c,d,n,m,q;double r=.1;
main(){
  scanf("%d",&n);
  for(m=1;!(n%4);n/=4)m*=2;
  a=sqrt(n);
  a-=(3+n-a*a)%4/2;
  for(;(d=r)-r;q++){b=q>>8;c=q%256;r=sqrt(n-a*a-b*b-c*c);}
  printf("%d %d %d %d ",a*m,b*m,c*m,d*m);}

उत्पादन

एक दिलचस्प विचित्रता यह है कि यदि आप एक वर्ग संख्या, N-(a*a)= 0 इनपुट करते हैं । लेकिन कार्यक्रम का पता चलता है कि 0%4= 0 और अगले वर्ग के लिए गिरावट। परिणामस्वरूप वर्ग संख्या इनपुट हमेशा छोटे वर्गों के समूह में विघटित हो जाते हैं जब तक कि वे फॉर्म के न हों 4^x

999999999
31621 1 161 294

805306368
16384 0 16384 16384

999950883
31621 1 120 221

1
0 0 0 1

2
1 0 0 1

5
2 0 0 1

9
2 0 1 2

25
4 0 0 3

36
4 0 2 4

49
6 0 2 3

81
8 0 1 4

121
10 1 2 4

गजब का! हर इनपुट के लिए 0.003 s! आप उन 5 चार्ट को वापस पा सकते हैं: 1. m=1पहले घोषणा करें main। 2. कथन scanfमें निष्पादित for। 3. के floatबजाय का उपयोग करें double। 4. n%4<1से छोटा है !(n%4)। 5. Printf के प्रारूप स्ट्रिंग में एक अप्रचलित स्थान है।
डेनिस


सुझावों के लिए धन्यवाद! n-=a*aकाम नहीं करता है, क्योंकि aबाद में इसे संशोधित किया जा सकता है (यह कुछ गलत जवाब देता है और मामलों की एक छोटी संख्या पर लटका देता है, जैसे 100 = 7 = 107।) मैंने बाकी सभी को शामिल किया। किसी चीज को छोटा करना अच्छा होगा, printfलेकिन मुझे लगता है कि भाषा को बदलने का एकमात्र उत्तर यही है। गति की कुंजी aजल्दी से एक अच्छे मूल्य पर बसने के लिए है । C में लिखा है और 256 ^ 2 से कम के खोज स्थान के साथ, यह शायद यहां का सबसे तेज कार्यक्रम है।
लेवल रिवर सेंट

सही है, क्षमा करें। printfमैक्रो या एरे का उपयोग किए बिना स्टेटमेंट को छोटा करना मुश्किल लगता है, जो थोक में कहीं और जोड़ देगा। भाषाओं को बदलना "आसान" तरीका लगता है। आपका दृष्टिकोण CJam में 82 बाइट का वजन होगा।
डेनिस

0

जावास्क्रिप्ट - 175 191 176 173 चार्ट

क्रूर बल, लेकिन उपवास।

फास्ट संपादित करें, लेकिन कुछ गंदा इनपुट के लिए पर्याप्त नहीं है। मुझे 4 की गुणा से कटौती का पहला चरण जोड़ना था।

संपादित करें 2 कार्य से छुटकारा पाएं, लूप के अंदर आउटपुट फिर बाहर निकलने की प्रतियोगिता को मजबूर करें

संपादित करें 3 0 एक वैध इनपुट नहीं है

v=(p=prompt)();for(m=1;!(v%4);m+=m)v/=4;for(a=-~(q=Math.sqrt)(v);a--;)for(w=v-a*a,b=-~q(w);b--;)for(x=w-b*b,c=-~q(x);c--;)(d=q(x-c*c))==~~d&&p([m*a, m*b, m*c, m*d],a=b=c='')

Ungolfed:

v = prompt();

for (m = 1; ! (v % 4); m += m) 
{
  v /= 4;
}
for (a = - ~Math.sqrt(v); a--;) /* ~ force to negative integer, changing sign lead to original value + 1 */
{
  for ( w = v - a*a, b = - ~Math.sqrt(w); b--;)
  {
    for ( x = w - b*b, c = - ~Math.sqrt(x); c--;)
    {
      (d = Math.sqrt(x-c*c)) == ~~d && prompt([m*a, m*b, m*c, m*d], a=b=c='') /* 0s a,b,c to exit loop */
    }
  }
}

उदाहरण आउटपुट

123456789
11111,48,10,8

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