जांचें कि क्या कोई संख्या एक पूर्ण वर्ग है


85

अगर एक नंबर एक पूर्ण वर्ग है, तो मैं कैसे जांच सकता हूं?

गति का कोई सरोकार नहीं है, अभी के लिए, सिर्फ काम करना।


1
बहुत बड़ी संख्या के लिए, एक तेज यादृच्छिक एल्गोरिदम है: petr-mitrichev.blogspot.com/2017/12/a-quadratic-week.html
थॉमस अहले

जवाबों:


117

किसी भी फ़्लोटिंग पॉइंट संगणना ( math.sqrt(x), या x**0.5) पर निर्भर होने के साथ समस्या यह है कि आप वास्तव में निश्चित नहीं हो सकते कि यह सटीक है (पर्याप्त रूप से बड़े पूर्णांक के लिए x, यह नहीं होगा, और अतिप्रवाह भी हो सकता है)। सौभाग्य से (यदि कोई जल्दी में नहीं; ;-) कई शुद्ध पूर्णांक दृष्टिकोण हैं, जैसे कि निम्नलिखित ...:

def is_square(apositiveint):
  x = apositiveint // 2
  seen = set([x])
  while x * x != apositiveint:
    x = (x + (apositiveint // x)) // 2
    if x in seen: return False
    seen.add(x)
  return True

for i in range(110, 130):
   print i, is_square(i)

संकेत: यह वर्गमूल के लिए "बेबीलोनियन एल्गोरिथ्म" पर आधारित है, विकिपीडिया देखें । यह किसी भी सकारात्मक संख्या के लिए काम करता है जिसके लिए आपके पास गणना के लिए पर्याप्त मेमोरी है जो पूरा होने के लिए आगे बढ़ता है; ;-)

संपादित करें : चलो एक उदाहरण देखें ...

x = 12345678987654321234567 ** 2

for i in range(x, x+2):
   print i, is_square(i)

यह प्रिंट, जैसा कि वांछित है (और समय की उचित मात्रा में; ;-):

152415789666209426002111556165263283035677489 True
152415789666209426002111556165263283035677490 False

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

और फिर x**7उस समस्या के आसपास काम करने का चतुर तरीका खोजिए, जो आपको मिलेगी,

OverflowError: long int too large to convert to float

जैसे-जैसे संख्या बढ़ती जा रही है, आपको अधिक से अधिक चतुर बनाना होगा।

अगर मैं था जल्दी में, ज़ाहिर है, मैं का उपयोग करेंगे gmpy - लेकिन फिर, मैं स्पष्ट रूप से पक्षपाती हूँ ;-)।

>>> import gmpy
>>> gmpy.is_square(x**7)
1
>>> gmpy.is_square(x**7 + 1)
0

हाँ, मुझे पता है, यह सिर्फ इतना आसान है कि यह धोखा देने जैसा महसूस करता है (सामान्य रूप से मैं पायथन की ओर थोड़ा सा महसूस करता हूं;; - कोई भी चतुराई नहीं, सिर्फ सही निर्देशन और सरलता (और, gmpy, सरासर गति के मामले में) ; -) ...


कहते हैं कि आप लेखक के बारे में क्या चाहते हैं, इस काम के लिए एक महान उपकरण की तरह लगता है।
माइक ग्राहम

3
बेबीलोनियन विधि अच्छी तरह से काम करती है, लेकिन आपको शून्य से विभाजन से बचने के लिए 0 और 1 के लिए विशेष मामलों की आवश्यकता होती है।
एमपेंकोव

2
वैसे, set([x])={x}
ऑस्कर मेडरोस

6
setOvekill नहीं है ? क्या बाबुल का अभिसरण नहीं है int(sqrt(x)), जहाँ हमें जाँच करनी है कि prev != nextक्या है?
टॉमस गंडोर

1
"मुझे पता है, यह सिर्फ इतना आसान है कि यह धोखा देने जैसा लगता है (सामान्य रूप से मैं पायथन की ओर थोड़ा महसूस करता हूं; यह सच है;)
अरुलक्स जेड

38

निकटतम पूर्णांक वर्गमूल पर जल्दी से शून्य करने के लिए न्यूटन की विधि का उपयोग करें, फिर इसे वर्ग करें और देखें कि क्या यह आपका नंबर है। देखें isqrt

पायथन th 3.8 है math.isqrt। अजगर के एक पुराने संस्करण का उपयोग कर रहे हैं, तो "के लिए देखो def isqrt(n)" कार्यान्वयन यहाँ

import math

def is_square(i: int) -> bool:
    return i == math.isqrt(i) ** 2

20

चूँकि आप फ़्लोटिंग पॉइंट कंप्यूटेशन (जैसे वर्गमूल की गणना के इन तरीकों) से निपटने के दौरान सटीक तुलनाओं पर निर्भर नहीं रह सकते, एक कम त्रुटि वाला कार्यान्वयन होगा

import math

def is_square(integer):
    root = math.sqrt(integer)
    return integer == int(root + 0.5) ** 2

कल्पना integerहै 9math.sqrt(9)हो सकता है 3.0, लेकिन यह कुछ ऐसा भी हो सकता है 2.99999या 3.00001, इसलिए परिणाम को सही से चुकाना विश्वसनीय नहीं है। यह जानते हुए कि intफर्श का मूल्य लेता है, 0.5पहले मूल्य द्वारा फ्लोट मूल्य में वृद्धि करना, हम उस मूल्य को प्राप्त करेंगे जो हम खोज रहे हैं यदि हम floatअभी भी एक सीमा में हैं जहां अभी भी एक ठीक पर्याप्त संकल्प है जिसके लिए हम देख रहे हैं। ।


5
यह थोड़ा बेहतर होगा करने के लिए बस करो if int(root + 0.5) ** 2 == integer:अगर intरूप में कार्य करता floorसंख्या के लिए हम के बारे में परवाह।
डेविड जॉनस्टोन

@ डेविड जॉनस्टोन, मैंने उस कार्यान्वयन का उपयोग करने के लिए इस पोस्ट को बदल दिया, जो मैं मानता हूं कि मेरे पास पुराने तरीके की तुलना में अच्छा है। किसी भी घटना में, अन्य तकनीकों में से कुछ का जिक्र यहां भी बेहतर और अधिक विश्वसनीय है।
माइक ग्राहम

मैं समझता हूं कि एफपी अनुमानित है, लेकिन क्या math.sqrt(9)वास्तव में कभी हो सकता है 2.99999? floatसी के लिए पायथन के नक्शे double, लेकिन मुझे लगता है कि 16-बिट एफपी प्रकार की तुलना में अधिक सटीक है, इसलिए शायद अगर आपके पास सी कंपाइलर था जो 8-बिट एफपी ("मिनीफ्लो") का उपयोग अपने doubleप्रकार के रूप में करता है ? मुझे लगता है कि यह तकनीकी रूप से संभव है, लेकिन मुझे लगता है कि पायथन को चलाने वाले किसी भी कंप्यूटर पर आज ऐसा नहीं है।
केन

@ नहीं, मैंने कहा था कि "कुछ ऐसा है" जैसा कि मैं इंगित करने के लिए अंतर्निहित अवधारणा पर हो रहा था; यह गारंटी नहीं है कि आपको मिलने वाला मूल्य सटीक मूल्य से थोड़ा कम नहीं होगा। मैं कल्पना नहीं कर सकता कि किसी विशेष प्रणाली पर math.sqrt(9)वापस आ जाएगा 2.99999, लेकिन वास्तविक परिणाम प्रणाली पर निर्भर है और सटीक होने की उम्मीद नहीं की जा सकती है।
माइक ग्राहम

1
यह फ़ंक्शन 1524157896662094002111556165262683035677489 जैसे बड़े वर्ग के लिए गलत है।
एक्यूमेनस

12

यदि आप रुचि रखते हैं, तो मेरे पास गणित स्टेक्सएक्सचेंज पर एक समान प्रश्न के लिए शुद्ध-गणित की प्रतिक्रिया है , "वर्गमूल निकालने की तुलना में तेजी से सही वर्गों का पता लगाना"

इस्क्वायर (n) का मेरा अपना कार्यान्वयन सबसे अच्छा नहीं हो सकता है, लेकिन मुझे यह पसंद है। मुझे इस सिद्धांत के साथ क्लिक करने के लिए, गणित सिद्धांत, डिजिटल कम्प्यूटेशन और अजगर प्रोग्रामिंग में कई महीनों का अध्ययन करने के लिए खुद को अन्य योगदानकर्ताओं से तुलना करते हुए, आदि की जानकारी दी। मुझे इसकी सादगी और दक्षता पसंद है। मैं बेहतर देखा havent। मुझे बताओ तुम क्या सोचते हो।

def isSquare(n):
    ## Trivial checks
    if type(n) != int:  ## integer
        return False
    if n < 0:      ## positivity
        return False
    if n == 0:      ## 0 pass
        return True

    ## Reduction by powers of 4 with bit-logic
    while n&3 == 0:    
        n=n>>2

    ## Simple bit-logic test. All perfect squares, in binary,
    ## end in 001, when powers of 4 are factored out.
    if n&7 != 1:
        return False

    if n==1:
        return True  ## is power of 4, or even power of 2


    ## Simple modulo equivalency test
    c = n%10
    if c in {3, 7}:
        return False  ## Not 1,4,5,6,9 in mod 10
    if n % 7 in {3, 5, 6}:
        return False  ## Not 1,2,4 mod 7
    if n % 9 in {2,3,5,6,8}:
        return False  
    if n % 13 in {2,5,6,7,8,11}:
        return False  

    ## Other patterns
    if c == 5:  ## if it ends in a 5
        if (n//10)%10 != 2:
            return False    ## then it must end in 25
        if (n//100)%10 not in {0,2,6}: 
            return False    ## and in 025, 225, or 625
        if (n//100)%10 == 6:
            if (n//1000)%10 not in {0,5}:
                return False    ## that is, 0625 or 5625
    else:
        if (n//10)%4 != 0:
            return False    ## (4k)*10 + (1,9)


    ## Babylonian Algorithm. Finding the integer square root.
    ## Root extraction.
    s = (len(str(n))-1) // 2
    x = (10**s) * 4

    A = {x, n}
    while x * x != n:
        x = (x + (n // x)) >> 1
        if x in A:
            return False
        A.add(x)
    return True

बहुत सीधा। पहले यह जांचता है कि हमारे पास एक पूर्णांक है, और उस पर एक सकारात्मक है। नहीं तो कोई बात नहीं है। यह 0 को सत्य के रूप में स्लिप देता है (आवश्यक है या फिर अगला ब्लॉक अनंत लूप है)।

कोड का अगला ब्लॉक बिट शिफ्ट और बिट लॉजिक ऑपरेशंस का उपयोग करके बहुत तेज उप-एल्गोरिथ्म में व्यवस्थित रूप से 4 की शक्तियों को हटा देता है। हम अंततः अपने मूल n का isquare नहीं पा रहे हैं, लेकिन एक k <n कि संभव हो तो 4 की शक्तियों से नीचे स्केल किया गया है। यह उस संख्या के आकार को कम कर देता है जिसके साथ हम काम कर रहे हैं और वास्तव में बेबीलोनियन पद्धति को गति प्रदान करते हैं, लेकिन अन्य जांचों को भी तेज करते हैं।

कोड का तीसरा ब्लॉक एक साधारण बूलियन बिट-लॉजिक परीक्षण करता है। किसी भी पूर्ण वर्ग के बाइनरी में, कम से कम तीन महत्वपूर्ण अंक 001 हैं। हमेशा। 4 की शक्तियों से उत्पन्न अग्रणी शून्य के लिए सहेजें, वैसे भी, जिसका पहले से ही हिसाब लगाया जा चुका है। यदि यह परीक्षण में विफल रहता है, तो आप तुरंत जानते हैं कि यह एक वर्ग नहीं है। यदि यह गुजरता है, तो आप सुनिश्चित नहीं हो सकते।

इसके अलावा, अगर हम एक परीक्षण मूल्य के लिए 1 के साथ समाप्त होते हैं तो परीक्षण संख्या मूल रूप से 4 की शक्ति थी, जिसमें शायद 1 भी शामिल है।

तीसरे ब्लॉक की तरह, चौथा, साधारण मापांक ऑपरेटर का उपयोग करके दशमलव में लोगों के स्थान के मूल्य का परीक्षण करता है, और पिछले परीक्षण के माध्यम से फिसलने वाले मूल्यों को पकड़ने के लिए जाता है। साथ ही एक मॉड 7, मॉड 8, मोड 9 और मॉड 13 टेस्ट।

कुछ प्रसिद्ध पूर्ण वर्ग पैटर्न के लिए कोड चेक का पांचवा ब्लॉक। 1 या 9 में समाप्त होने वाली संख्याएँ चार के कई से पहले होती हैं। और 5 में समाप्त होने वाली संख्या 5625, 0625, 225, या 025 में समाप्त होनी चाहिए। मैंने दूसरों को शामिल किया था, लेकिन एहसास हुआ कि वे बेमानी थे या वास्तव में कभी उपयोग नहीं किए गए थे।

अंत में, कोड का छठा खंड बहुत अधिक दिखता है जो शीर्ष उत्तरदाता - एलेक्स मार्टेली - उत्तर है। मूल रूप से प्राचीन बेबीलोनियन एल्गोरिथ्म का उपयोग करके वर्गमूल को पाता है, लेकिन फ्लोटिंग पॉइंट को अनदेखा करते हुए इसे पूर्णांक मानों तक सीमित कर देता है। गति और परीक्षण योग्य हैं मूल्यों के परिमाण का विस्तार दोनों के लिए किया। मैंने सूचियों के बजाय सेट का उपयोग किया क्योंकि इसमें बहुत कम समय लगता है, मैंने विभाजन के बजाय बिट शिफ्ट्स का उपयोग दो से किया, और मैंने चालाकी से एक प्रारंभिक प्रारंभ मूल्य को बहुत अधिक कुशलता से चुना।

वैसे, मैंने एलेक्स मार्टेली की अनुशंसित परीक्षण संख्या का परीक्षण किया, साथ ही कुछ संख्याओं के कारण कई आदेशों का परिमाण बड़ा हुआ, जैसे:

x=1000199838770766116385386300483414671297203029840113913153824086810909168246772838680374612768821282446322068401699727842499994541063844393713189701844134801239504543830737724442006577672181059194558045164589783791764790043104263404683317158624270845302200548606715007310112016456397357027095564872551184907513312382763025454118825703090010401842892088063527451562032322039937924274426211671442740679624285180817682659081248396873230975882215128049713559849427311798959652681930663843994067353808298002406164092996533923220683447265882968239141724624870704231013642255563984374257471112743917655991279898690480703935007493906644744151022265929975993911186879561257100479593516979735117799410600147341193819147290056586421994333004992422258618475766549646258761885662783430625 ** 2
for i in range(x, x+2):
    print(i, isSquare(i))

निम्नलिखित परिणाम मुद्रित:

1000399717477066534083185452789672211951514938424998708930175541558932213310056978758103599452364409903384901149641614494249195605016959576235097480592396214296565598519295693079257885246632306201885850365687426564365813280963724310434494316592041592681626416195491751015907716210235352495422858432792668507052756279908951163972960239286719854867504108121432187033786444937064356645218196398775923710931242852937602515835035177768967470757847368349565128635934683294155947532322786360581473152034468071184081729335560769488880138928479829695277968766082973795720937033019047838250608170693879209655321034310764422462828792636246742456408134706264621790736361118589122797268261542115823201538743148116654378511916000714911467547209475246784887830649309238110794938892491396597873160778553131774466638923135932135417900066903068192088883207721545109720968467560224268563643820599665232314256575428214983451466488658896488012211237139254674708538347237589290497713613898546363590044902791724541048198769085430459186735166233549186115282574626012296888817453914112423361525305960060329430234696000121420787598967383958525670258016851764034555105019265380321048686563527396844220047826436035333266263375049097675787975100014823583097518824871586828195368306649956481108708929669583308777347960115138098217676704862934389659753628861667169905594181756523762369645897154232744410732552956489694024357481100742138381514396851789639339362228442689184910464071202445106084939268067445115601375050153663645294106475257440167535462278022649865332161044187890625 True
1000399717477066534083185452789672211951514938424998708930175541558932213310056978758103599452364409903384901149641614494249195605016959576235097480592396214296565598519295693079257885246632306201885850365687426564365813280963724310434494316592041592681626416195491751015907716210235352495422858432792668507052756279908951163972960239286719854867504108121432187033786444937064356645218196398775923710931242852937602515835035177768967470757847368349565128635934683294155947532322786360581473152034468071184081729335560769488880138928479829695277968766082973795720937033019047838250608170693879209655321034310764422462828792636246742456408134706264621790736361118589122797268261542115823201538743148116654378511916000714911467547209475246784887830649309238110794938892491396597873160778553131774466638923135932135417900066903068192088883207721545109720968467560224268563643820599665232314256575428214983451466488658896488012211237139254674708538347237589290497713613898546363590044902791724541048198769085430459186735166233549186115282574626012296888817453914112423361525305960060329430234696000121420787598967383958525670258016851764034555105019265380321048686563527396844220047826436035333266263375049097675787975100014823583097518824871586828195368306649956481108708929669583308777347960115138098217676704862934389659753628861667169905594181756523762369645897154232744410732552956489694024357481100742138381514396851789639339362228442689184910464071202445106084939268067445115601375050153663645294106475257440167535462278022649865332161044187890626 False

और इसने 0.33 सेकंड में यह कर दिखाया।

मेरी राय में, मेरा एल्गोरिथ्म एलेक्स मार्टेली के समान ही है, इसके सभी लाभों के साथ, लेकिन इसमें अतिरिक्त लाभ है अत्यधिक कुशल सरल-परीक्षण अस्वीकार जो बहुत समय बचाते हैं, परीक्षण की शक्तियों के आकार में कमी का उल्लेख नहीं करना। 4, जो गति, दक्षता, सटीकता और परीक्षण करने योग्य संख्याओं के आकार में सुधार करता है। गैर-पायथन कार्यान्वयन में संभवतः विशेष रूप से सच है।

बेबीलोन मूल निष्कर्षण को लागू करने से पहले सभी पूर्णांकों का 99% गैर-वर्ग के रूप में खारिज कर दिया जाता है, और 2/3 में पूर्णांक को अस्वीकार करने के लिए बेबीलोन ले जाएगा। और हालांकि ये परीक्षण इस प्रक्रिया को तेज नहीं करते हैं, लेकिन सभी परीक्षण संख्याओं में कमी 4 की सभी शक्तियों को विभाजित करके एक विषमता को वास्तव में बेबीलोनियन परीक्षण को तेज करती है।

मैंने एक समय तुलना परीक्षण किया। मैंने उत्तराधिकार में 1 से 10 मिलियन तक के सभी पूर्णांक का परीक्षण किया। केवल बेबीलोनियन विधि का उपयोग करके स्वयं (मेरे विशेष रूप से सिलसिलेवार प्रारंभिक अनुमान के साथ) ने मेरी सतह 3 को औसतन 165 सेकंड (100% सटीकता के साथ) लिया। मेरे एल्गोरिथ्म (बेबीलोन को छोड़कर) में सिर्फ तार्किक परीक्षणों का उपयोग करते हुए, इसमें 127 सेकंड लगे, इसने 99% सभी पूर्णांकों को गैर-वर्ग के रूप में बिना किसी सही वर्ग को अस्वीकार किए अस्वीकार कर दिया। जो पूर्णांक पास हुए, उनमें से केवल 3% पूर्ण वर्ग (बहुत अधिक घनत्व) थे। उपरोक्त पूर्ण एल्गोरिथ्म का उपयोग करना जो तार्किक परीक्षणों और बेबीलोनियन रूट निष्कर्षण दोनों को नियोजित करता है, हमारे पास 100% सटीकता है, और परीक्षण केवल 14 सेकंड में पूरा होता है। पहले 100 मिलियन पूर्णांकों का परीक्षण करने में लगभग 2 मिनट 45 सेकंड लगते हैं।

संपादित करें: मैं समय को और नीचे लाने में सक्षम हूं। मैं अब 1 मिनट 40 सेकंड में पूर्णांक 0 से 100 मिलियन तक का परीक्षण कर सकता हूं। डेटा प्रकार और सकारात्मकता की जाँच में बहुत समय बर्बाद होता है। पहले दो चेक हटा दें और मैंने प्रयोग को एक मिनट घटा दिया। यह मान लेना चाहिए कि उपयोगकर्ता यह जानने के लिए पर्याप्त स्मार्ट है कि नकारात्मक और तैरने वाले सही वर्ग नहीं हैं।


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

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

खैर, यह निश्चित रूप से एक अच्छा और अनोखा जवाब है और अगर भविष्य में मेरे पास कुछ समय है तो मैं इसके साथ खेलना चाहूंगा, कुछ समय के लिए छोटे-छोटे अपराधों की संख्या को देखने की कोशिश करता हूं कि क्या किसी दिए गए बिट्स पर एक इष्टतम संख्या मिल सकती है ।
राष्ट्रपति जेम्स के। पोल्क

हर तरह से, मेरे कोड का परीक्षण करें। इसे तोड़ दो। Im एक प्रोग्रामर नहीं व्यापार द्वारा, Im एक गणित प्रमुख है। अजगर सिर्फ एक शौक है। अगर इसकी औसत से अधिक कुशल हो तो आईडी को उत्सुक होना चाहिए।
CogitoErgoCogitoSum

1
यदि आप अभी भी रुचि रखते हैं तो अनिवार्य रूप से कुछ दिलचस्प जवाबों के साथ यहां एक डुप्लिकेट प्रश्न है, विशेष रूप से A.Rex का उत्तर
राष्ट्रपति जेम्स के। पोल्क

12
import math

def is_square(n):
    sqrt = math.sqrt(n)
    return (sqrt - int(sqrt)) == 0

एक पूर्ण वर्ग एक संख्या है जिसे दो समान पूर्णांक के उत्पाद के रूप में व्यक्त किया जा सकता है। math.sqrt(number)वापस आ जाओ floatint(math.sqrt(number))के परिणाम निकालता है int

यदि वर्गमूल एक पूर्णांक है, जैसे 3, उदाहरण के लिए, तो math.sqrt(number) - int(math.sqrt(number))0 होगा, और ifकथन होगा False। यदि स्क्वायर रूट 3.2 की तरह एक वास्तविक संख्या थी, तो यह होगा Trueऔर "यह एक पूर्ण वर्ग नहीं है" प्रिंट करेगा ।

यह 152415789666209426002111556165262683035677490 जैसे बड़े गैर-वर्ग के लिए विफल रहता है


बदलें if (math.sqrt(number)-int(math.sqrt(number))):करने के लिए a=math.sqrt(number)तो के लिए एक और लाइन: if a-int(a):। यह तब से है जब इसे केवल एक बार वर्गमूल की गणना करनी होती है, जो बड़े n के लिए imo महत्वपूर्ण है
unseen_rider

@JamesKPolk ऐसा क्यों है?
user1717828

Im बहुत यकीन है कि sqrt - int (sqrt) sqrt% 1 के समान है। आपका संपूर्ण कार्य केवल
गणित में

6

मेरा उत्तर है:

def is_square(x):
    return x**.5 % 1 == 0

यह मूल रूप से एक वर्गमूल करता है, फिर पूर्णांक भाग को हटाने के लिए 1 से modulo और यदि परिणाम 0 है तो Trueअन्यथा वापस लौटें False। इस स्थिति में x कोई भी बड़ी संख्या हो सकती है, बस उतने बड़े नहीं जितने कि अधिकतम फ्लोट संख्या है जिसे अजगर संभाल सकता है: 1.7976931348623157e + 308

यह एक बड़े गैर-वर्ग के लिए गलत है जैसे 152415789666209426002111556165262683035677490।


5

इस का उपयोग कर हल किया जा सकता मॉड्यूल मनमाना परिशुद्धता वर्ग जड़ों और "शुद्धता" के लिए आसान चेकों पाने के लिए:decimal

import math
from decimal import localcontext, Context, Inexact

def is_perfect_square(x):
    # If you want to allow negative squares, then set x = abs(x) instead
    if x < 0:
        return False

    # Create localized, default context so flags and traps unset
    with localcontext(Context()) as ctx:
        # Set a precision sufficient to represent x exactly; `x or 1` avoids
        # math domain error for log10 when x is 0
        ctx.prec = math.ceil(math.log10(x or 1)) + 1  # Wrap ceil call in int() on Py2
        # Compute integer square root; don't even store result, just setting flags
        ctx.sqrt(x).to_integral_exact()
        # If previous line couldn't represent square root as exact int, sets Inexact flag
        return not ctx.flags[Inexact]

वास्तव में विशाल मूल्यों के साथ प्रदर्शन के लिए:

# I just kept mashing the numpad for awhile :-)
>>> base = 100009991439393999999393939398348438492389402490289028439083249803434098349083490340934903498034098390834980349083490384903843908309390282930823940230932490340983098349032098324908324098339779438974879480379380439748093874970843479280329708324970832497804329783429874329873429870234987234978034297804329782349783249873249870234987034298703249780349783497832497823497823497803429780324
>>> sqr = base ** 2
>>> sqr ** 0.5  # Too large to use floating point math
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: int too large to convert to float

>>> is_perfect_power(sqr)
True
>>> is_perfect_power(sqr-1)
False
>>> is_perfect_power(sqr+1)
False

यदि आप परीक्षण किए जा रहे मूल्य के आकार में वृद्धि करते हैं, तो यह अंततः धीमा हो जाता है (200,000 बिट वर्ग के लिए एक सेकंड के करीब होता है), लेकिन अधिक मध्यम संख्या (कहते हैं, 20,000 बिट्स) के लिए, यह अभी भी एक मानव की तुलना में तेज़ होगा व्यक्तिगत मूल्य (मेरी मशीन पर ~ 33 एमएस)। लेकिन चूंकि गति आपकी प्राथमिक चिंता नहीं थी, इसलिए पायथन के मानक पुस्तकालयों के साथ यह करने का एक अच्छा तरीका है।

बेशक, यह उपयोग करने के लिए बहुत तेज़ होगा gmpy2और बस परीक्षण करेगा gmpy2.mpz(x).is_square(), लेकिन अगर तीसरे पक्ष के पैकेज आपकी चीज नहीं हैं, तो उपरोक्त काफी अच्छी तरह से काम करता है।


5

मैंने अभी ऊपर दिए गए कुछ उदाहरणों पर थोड़े से बदलाव को एक दूसरे धागे पर ( सही वर्ग ढूंढते हुए) पोस्ट किया है और मैंने सोचा कि मैं यहाँ जो कुछ भी पोस्ट कर रहा हूँ उसमें थोड़ा बदलाव शामिल होगा (nsqrt का उपयोग एक अस्थायी चर के रूप में), यदि यह ब्याज की है / उपयोग:

import math

def is_square(n):
  if not (isinstance(n, int) and (n >= 0)):
    return False 
  else:
    nsqrt = math.sqrt(n)
    return nsqrt == math.trunc(nsqrt)

यह एक बड़े गैर-वर्ग के लिए गलत है जैसे 152415789666209426002111556165262683035677490।


2

यह मेरी विधि है:

def is_square(n) -> bool:
    return int(n**0.5)**2 == int(n)

संख्या का वर्गमूल लें। पूर्णांक में परिवर्तित करें। चौक लो। यदि संख्या समान हैं, तो यह एक पूर्ण वर्ग है अन्यथा नहीं।

यह 15241578966620942620051556165263283035677489 जैसे बड़े वर्ग के लिए गलत है


नकारात्मक संख्या के लिए काम नहीं करेंगे, लेकिन अभी भी एक महान समाधान!
रिक एम।

1

आप बाउंडेड स्क्वायर रूट के लिए बाइनरी-खोज कर सकते हैं। यह देखने के लिए कि क्या यह मूल मूल्य से मेल खाता है, परिणाम को स्क्वायर करें।

आप शायद FogleBirds उत्तर के साथ बेहतर हैं - हालांकि सावधान रहें, चूंकि फ्लोटिंग पॉइंट अंकगणितीय अनुमानित है, जो इस दृष्टिकोण को बंद कर सकता है। आप सिद्धांत रूप में एक बड़े पूर्णांक से एक झूठी सकारात्मक प्राप्त कर सकते हैं जो कि एक सटीक वर्ग से अधिक है, उदाहरण के लिए, खोई हुई सटीकता के कारण।


1

यदि मापांक (शेष) को वर्गमूल से विभाजित करने से बचे 0 है, तो यह एक पूर्ण वर्ग है।

def is_square(num: int) -> bool:
    return num % math.sqrt(num) == 0

मैंने इसे 1000 तक सही वर्गों की सूची के खिलाफ जांचा।



0

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

पहला सवाल जो आपको आम तौर पर मिलेगा वो है "डोंट!" और यह सच है कि पायथन में, टाइपेकिटिंग आमतौर पर करना सही नहीं है।

उन दुर्लभ अपवादों के लिए, हालांकि, संख्या के स्ट्रिंग प्रतिनिधित्व में एक दशमलव बिंदु की तलाश करने के बजाय, करने वाली बात का उपयोग आइंस्टीन फ़ंक्शन का उपयोग किया जाता है:

>>> isinstance(5,int)
True
>>> isinstance(5.0,int)
False

बेशक यह एक मान के बजाय चर पर लागू होता है। यदि मैं यह निर्धारित करना चाहता था कि क्या मान पूर्णांक था, तो मैं यह करूंगा:

>>> x=5.0
>>> round(x) == x
True

लेकिन जैसा कि सभी ने विस्तार से कवर किया है, इस तरह की चीज़ के सबसे गैर-खिलौना उदाहरणों में विचार करने के लिए फ्लोटिंग-पॉइंट मुद्दे हैं।


1
"यह एक मान के बजाय चर पर लागू होता है" क्या मतलब है? आप समस्याओं के बिना दौर (5.0) == 5.0 और आइंस्टीन (x, int) का उपयोग कर सकते हैं। (और OOWTDI सिर्फ x.is_integer () को कॉल करने के लिए है)
Veky

0

यदि आप एक सीमा पर लूप करना चाहते हैं और हर संख्या के लिए कुछ करना चाहते हैं जो एक पूर्ण वर्ग नहीं है, तो आप कुछ ऐसा कर सकते हैं:

def non_squares(upper):
    next_square = 0
    diff = 1
    for i in range(0, upper):
        if i == next_square:
            next_square += diff
            diff += 2
            continue
        yield i

यदि आप एक पूर्ण वर्ग के लिए हर संख्या के लिए कुछ करना चाहते हैं, तो जनरेटर और भी आसान है:

(n * n for n in range(upper))

0

मुझे लगता है कि यह काम करता है और बहुत सरल है:

import math

def is_square(num):
    sqrt = math.sqrt(num)
    return sqrt == int(sqrt)

यह एक बड़े गैर-वर्ग के लिए गलत है जैसे 152415789666209426002111556165262683035677490।


यह उपरोक्त उत्तर के समान है।
कोवलस्की

0

बिना @Alex Martelli के समाधान का एक संस्करण set

कब x in seenहै True:

  • ज्यादातर मामलों में, यह अंतिम जोड़ा गया है, उदाहरण के लिए 1022 के xअनुक्रम 511, 256, 129, 68, 41, 32, 31 , 31 का उत्पादन होता है ;
  • कुछ मामलों में (यानी, सही वर्गों के पूर्ववर्तियों के लिए), यह दूसरा-से-आखिरी एक जोड़ा है, जैसे 1023 511, 256, 129, 68, 41, 32 , 31, 32 का उत्पादन करता है

इसलिए, यह जितनी जल्दी हो सके बंद करने के लिए पर्याप्त होता है जैसे कि वर्तमान xपिछले एक से अधिक या उसके बराबर है:

def is_square(n):
    assert n > 1
    previous = n
    x = n // 2
    while x * x != n:
        x = (x + (n // x)) // 2
        if x >= previous:
            return False
        previous = x
    return True

x = 12345678987654321234567 ** 2
assert not is_square(x-1)
assert is_square(x)
assert not is_square(x+1)

1 <n <10 ** 7 के लिए परीक्षण किए गए मूल एल्गोरिथ्म के साथ समानता। एक ही अंतराल पर, यह थोड़ा सरल संस्करण लगभग 1.4 गुना तेज है।


0
a=int(input('enter any number'))
flag=0
for i in range(1,a):
    if a==i*i:
        print(a,'is perfect square number')
        flag=1
        break
if flag==1:
    pass
else:
    print(a,'is not perfect square number')

हालाँकि यह कोड समस्या को हल कर सकता है, एक अच्छे उत्तर को यह भी बताना चाहिए कि कोड क्या करता है और यह कैसे मदद करता है।
BDL

0

विचार i = 1 से फर्श (sqrt (n)) पर एक लूप चलाने के लिए है, तो जाँच करें कि क्या वर्ग इसे n बनाता है।

bool isPerfectSquare(int n) 
{ 
    for (int i = 1; i * i <= n; i++) { 

        // If (i * i = n) 
        if ((n % i == 0) && (n / i == i)) { 
            return true; 
        } 
    } 
    return false; 
} 

-3
import math

def is_square(n):
    sqrt = math.sqrt(n)
    return sqrt == int(sqrt)

यह 152415789666209426002111556165262683035677490 जैसे बड़े गैर-वर्ग के लिए विफल रहता है


2
यह एक कोड केवल उत्तर है। कृपया थोड़ा तर्क प्रदान करें।
११:०२

आप उस @hotzst के माध्यम से अपना रास्ता नहीं बना सकते? यह सही समझ में आता है और Im अजगर में भी विशेषज्ञ नहीं है। इसका सबसे बड़ा परीक्षण नहीं है, लेकिन यह सिद्धांत और छोटे मामलों दोनों के लिए मान्य है।
CogitoErgoCogitoSum 22

1
@CogitoErgoCogitoSum: आप नहीं समझते। Google जैसे खोज इंजन का उपयोग करके खोजों द्वारा कोड-केवल उत्तर नहीं मिलते हैं। क्या कोई जवाब समझ सकता है अप्रासंगिक है।
राष्ट्रपति जेम्स के पोल्क
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.