वर्ग संख्या अंक घनत्व


17

किसी संख्या का वर्ग संख्या अंक घनत्व (SNDD) - खुद के द्वारा आविष्कार किया गया - संख्या की लंबाई तक लगातार अंकों में पाए जाने वाले वर्ग संख्याओं की गिनती का अनुपात है। उदाहरण के लिए, 169 एक 3-अंकीय संख्या है जिसमें 4 वर्ग संख्याएँ हैं - 1, 9, 16, 169 - और इस प्रकार 4/3 या 1.33 का वर्ग संख्या अंक घनत्व है। 4-अंकीय संख्या 1444 में 6 वर्ग हैं - 1, 4, 4, 4, 144, 1444 - और इस प्रकार 6/4, या 1.5 का अनुपात। पिछले उदाहरण में ध्यान दें कि वर्गों को दोहराया जाने की अनुमति है। साथ ही, 441 की अनुमति नहीं है, क्योंकि यह संख्या 1444 के अंदर लगातार नहीं मिल सकती है।

आपका कार्य एक प्रोग्राम लिखना है जो कि उच्चतम वर्ग संख्या अंक घनत्व के साथ संख्या के लिए दिए गए रेंज ए - बी (समावेशी) की खोज करता है। आपके कार्यक्रम को निम्नलिखित विशिष्टताओं का पालन करना चाहिए:

  • 1, 1,000,000,000 (1 बिलियन) की सीमा में इनपुट A, B को लें। उदाहरण:sndd 50 1000
  • परिणामस्वरूप सबसे बड़ी SNDD के साथ संख्या के रूप में लौटें। एक टाई के मामले में, सबसे छोटी संख्या लौटाएं।
  • 0 किसी भी रूप में 0, 00, 000, आदि किसी वर्ग के रूप में नहीं गिना जाता है, न ही वर्ग 0 से शुरू होता है, जैसे 049 या 0049।
  • ध्यान दें कि पूरी संख्या में एक वर्ग संख्या नहीं है।

उदाहरण:

sndd 14000 15000
Output: 14441

sndd 300 500
Output: 441

बोनस: 1 और 1,000,000,000 के बीच सबसे बड़ी SNDD के साथ संख्या क्या है? क्या आप साबित कर सकते हैं कि क्या यह सबसे बड़ा संभव है, या उच्च श्रेणी में कोई बड़ा हो सकता है?

वर्तमान स्कोर:

  1. रूबी: 142
  2. विंडोज पॉवरशेल: 153
  3. स्काला: 222
  4. पायथन: 245

अब जब एक उत्तर का चयन किया गया है, तो यहां जावास्क्रिप्ट में मेरा (अपवित्र) संदर्भ कार्यान्वयन है: http://jsfiddle.net/ywc25/2/

जवाबों:


3

रूबी 1.9, 142 अक्षर

$><<($*[0]..$*[1]).map{|a|n=0.0;(1..s=a.size).map{|i|n+=a.chars.each_cons(i).count{|x|x[0]>?0&&(r=x.join.to_i**0.5)==r.to_i}};[-n/s,a]}.min[1]
  • (139 -> 143): एक टाई के मामले में फिक्स्ड आउटपुट।

@Ventero: दोनों परीक्षण मामलों में विफल रहता है। मुझे लगता है कि आप के साथ 0 * शुरू करने वर्गों बाहर छोड़ने के लिए भूल जाते हैं
mellamokb

@mellamokb: उन्हें यहाँ असफल नहीं है: $ ruby1.9 sndd.rb 14000 15000 => 14441x[0]>?0चौकों के लिए चेक 0.
वेंटरो

@ ममलमोक: यह यहां परीक्षण मामलों को पारित करता है।
नबं

@Ventero: हम्म .. मेरे माणिक परीक्षण वातावरण के साथ कुछ गलत होना चाहिए। मैं रूबी से परिचित नहीं हूं। मेरे पास १. think think हैं, मुझे लगता है, और मैंने sdd.rb में ऊपर दिए गए कोड को कॉपी / पेस्ट किया है, फिर ruby sndd.rb 14000 15000विंडोज से
चलाऊंगा

@ मैमेलमोकब: रूबी 1.8 में, ?0एक फ़िक्नम है, जबकि रूबी 1.8 में यह एक स्ट्रिंग है, इसलिए मैंने जो तुलना की है, उसका मतलब रूबी संस्करण के आधार पर एक अलग अर्थ है (वास्तव में इसे 1.8 में अपवाद छोड़ देना चाहिए)। इसलिए मैंने शीर्षक में संस्करण 1.9 का स्पष्ट रूप से उल्लेख किया है।
वेंटरो

8

बोनस का उत्तर देना: संख्याओं के लिए सबसे अच्छा स्कोर <1e9 5/3 = 1.666 है ..., 144411449 (और शायद अन्य?) द्वारा उत्पन्न।

लेकिन आप बड़ी संख्या के साथ बेहतर कर सकते हैं। आम तौर पर अगर n का स्कोर x है, तो आप n की दो प्रतियों को समेट सकते हैं और समान स्कोर x प्राप्त कर सकते हैं। यदि आप भाग्यशाली हैं और n के पास पहले और अंतिम अंक समान हैं, तो आप उन अंकों में से एक को अधिमिलन में छोड़ सकते हैं और अपने स्कोर में थोड़ा सुधार कर सकते हैं (वर्गों की संख्या दोगुनी से कम और अंकों की संख्या से दोगुने से भी कम) ।

n = 11449441 का स्कोर 1.625 है और इसका पहला और अंतिम अंक समान है। उस तथ्य का उपयोग करते हुए, हमें अंकों का निम्नलिखित क्रम मिलता है:

1.625 for 11449441
1.666 for 114494411449441
1.682 for 1144944114494411449441
1.690 for 11449441144944114494411449441
1.694 for 114494411449441144944114494411449441

जो संख्याओं का एक अनंत क्रम देता है जो पिछले संख्याओं की तुलना में कड़ाई से (यद्यपि घटकर) बेहतर हैं, और संख्याओं के लिए सबसे अच्छा स्कोर की तुलना में सभी पहले 2 बेहतर हैं <1e9।

यह क्रम कुल मिलाकर सबसे अच्छा नहीं हो सकता है। यह एक परिमित स्कोर (12/7 = 1.714) में परिवर्तित हो जाता है और सीमा से बेहतर स्कोर के साथ अन्य संख्याएं हो सकती हैं।

संपादित करें : एक बेहतर अनुक्रम, 1.75 में परिवर्तित होता है

1.600 14441
1.667 144414441
1.692 1444144414441
1.706 14441444144414441
1.714 144414441444144414441

दिलचस्प! आप सिर्फ यह साबित कर सकते हैं कि यह क्रम वास्तव में अनंत है।
20ult में ESultanik

@ सुल्तानिक: वास्तव में नहीं, क्योंकि यहाँ कोई आवश्यकता नहीं है कि समग्र संख्या एक पूर्ण वर्ग हो।
मेलमोकब

@ESutanik: मुझे नहीं लगता कि अनुक्रम संबंधित है, क्योंकि उन्हें पूरी संख्या एक वर्ग की आवश्यकता होती है - मेरे अनुक्रम में केवल वर्ग छोटे अनुवर्ती (<= 5 अंक) हैं, जब तक कि दुर्घटना से कोई बड़ा न हो।
कीथ रान्डेल

आप एक अनंत अनुक्रम भी उत्पन्न कर सकते हैं जहां लिंक एक अतिरिक्त वर्ग उत्पन्न करता है, अर्थात, 44 में समाप्त होने वाली और 1 से शुरू होने वाली प्रत्येक संयोजन के साथ 441 होगा। एक तुच्छ उदाहरण अनुक्रम 144, 144144, 144144144, आदि होगा
mellamokb

@ ममलोकब वाह, मैं पूरी तरह से चूक गया कि संख्या को एक पूर्ण वर्ग नहीं होना चाहिए। आप सही हे।
ESultanik

3

विंडोज पॉवरशेल, 153 154 155 164 174

$a,$b=$args
@($a..$b|sort{-(0..($l=($s="$_").length)|%{($c=$_)..$l|%{-join$s[$c..$_]}}|?{$_[0]-48-and($x=[math]::sqrt($_))-eq[int]$x}).Count/$l},{$_})[0]

एक-बाइट में कमी के लिए वेंटरो को धन्यवाद मैं खुद को खोजने के लिए बहुत बेवकूफ था।

154-बाइट संस्करण समझाया:

$a,$b=$args   # get the two numbers. We expect only two arguments, so that
              # assignment will neither assign $null nor an array to $b.

@(   # @() here since we might iterate over a single number as well
    $a..$b |  # iterate over the range
        sort {   # sort
            (   # figure out all substrings of the number
                0..($l=($s="$_").length) | %{  # iterate to the length of the
                                               # string – this will run off
                                               # end, but that doesn't matter

                    ($c=$_)..$l | %{       # iterate from the current position
                                           # to the end

                        -join$s[$c..$_]    # grab a range of characters and
                                           # make them into a string again
                    }
                } | ?{                     # filter the list
                    $_[0]-48 -and          # must not begin with 0
                    ($x=[math]::sqrt($_))-eq[int]$x  # and the square root
                                                     # must be an integer
                }

            ).Count `  # we're only interested in the count of square numbers
            / $l       # divided by the length of the number
        },
        {-$_}  # tie-breaker
)[-1]  # select the last element which is the smallest number with the
       # largest SNDD

2

पायथन, 245 256

import sys
def t(n,l):return sum(map(lambda x:int(x**0.5+0.5)**2==x,[int(n[i:j+1])for i in range(l)for j in range(i,l)if n[i]!='0']))/float(l)
print max(map(lambda x:(x,t(str(x),len(str(x)))),range(*map(int,sys.argv[1:]))),key=lambda y:y[1])[0]
  • 256 → 245: कीथ रान्डल से एक टिप के लिए तर्क पार्सिंग कोड को साफ किया ।

यदि stdinकमांड लाइन के तर्कों के विपरीत रेंज को पढ़ा गया तो यह बहुत कम हो सकता है ।

संपादित करें:

बोनस के संबंध में, मेरे प्रयोग निम्नलिखित सुझाव देते हैं:

अनुमान १हर n के लिए ∈ ℕ , में नंबरn सबसे बड़ा SNDD साथ पूरी तरह से अंक 1, 4, और 9 शामिल होना चाहिए।

अनुमान 2.n ∈ ℕ ∀ मैं ℕ ∈ n : SNDD ( एन ) ≥ SNDD ( मैं )।

प्रमाण स्केच । 1, 4 और 9 अंक वाले वर्गों का सेट संभवत: परिमित है । ∎


कोशिशrange(*map(int,sys.argv[1:]))
कीथ रान्डेल

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

@ Arnt के उत्तर से अनुमान 2 गलत है, क्योंकि SNDD का मूल्य मनमाने ढंग से बड़ा किया जा सकता है।
मेलमोकब

2

स्काला, 222

object O extends App{def q(i: Int)={val x=math.sqrt(i).toInt;x*x==i}
println((args(0).toInt to args(1).toInt).maxBy(n=>{val s=n+""
s.tails.flatMap(_.inits).filter(x=>x.size>0&&x(0)!='0'&&q(x.toInt)).size.toFloat/s.size}))}

(स्काला 2.9 आवश्यक)


1

बोनस प्रश्न पर विचार: सीमा के बाहर उच्चतम संभव SNDD अनंत है।

कम से कम, यदि मैं प्रश्न को सही ढंग से पढ़ता हूं, तो 100 (10 * 10) जैसे वर्ग की गणना होती है।

यदि आप संख्या 275625 मानते हैं, तो स्कोर 5/6 है, क्योंकि 25, 625, 5625, 75625 और 275625 सभी वर्ग हैं।

2 शून्य का जोड़ देता है: 27562500, जिसका स्कोर 10/8 है। इस क्रम की सीमा 5/2 = 2.5 है

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

बेशक, यह एक बहुत अच्छा समाधान नहीं है, लेकिन यह सबूत है कि एसएनडीडी के लिए कोई ऊपरी सीमा नहीं है।


"उसी पंक्तियों के साथ, आप ऐसे वर्ग पा सकते हैं, जो वांछित संख्या में छोटे वर्गों में समाप्त होते हैं। मैं इस बात का प्रमाण दे सकता हूं, लेकिन आप शायद इस विचार को प्राप्त कर सकते हैं।" मैं इस प्रमाण को विकसित होते हुए देखना चाहता हूँ। मैं 25 में समाप्त होने वाले सबसे बड़े अनुक्रम को देख सकता हूं जहां 25 में समाप्त होने वाली प्रत्येक संख्या 275625 है। कोई अंक 1-9 नहीं है जो आप शुरुआत में एक और वर्ग खोजने के लिए रख सकते हैं। क्या आप कह रहे हैं कि यह मनमाने ढंग से बड़ा बनाया जा सकता है, और यदि हां, तो कैसे और क्यों?
मेलमोकब

हां, अनुक्रम को मनमाने ढंग से बड़ा किया जा सकता है। इसका प्रमाण यह है: यदि * a = b आपकी प्रारंभिक संख्या है, तो (a + 10 ^ c) * (a + 10 ^ c) भी b में समाप्त होता है यदि c पर्याप्त रूप से बड़ा है। यदि आप वर्ग लेते हैं तो व्यवहार में छोटी संख्या हो सकती है जो b में समाप्त होती है। उदाहरण के लिए, 18275625 एक वर्ग (4275 * 4275) है।
अरिंत वीनेस्ट्रा

वर्गों को खोजने के लिए कोड: jsfiddle.net/zVSuZ/2
mellamokb

@ अरंट: यहां इस तरह के (तुच्छ) अनुक्रम, 5 ^ 2 (1/2), 55 ^ 2 (2/4), 5055 ^ 2 (3/8), 50005055 ^ 2 (4/16), आदि हैं। जहां प्रत्येक जोड़ 5 * 10 ^ n है, जहां n पिछली प्रविष्टि से दोगुना है। प्रत्येक प्रविष्टि स्कोर में छोटी होती है, लेकिन ऐड टू 00 के नियम को लागू करते समय सीमा थोड़ी अधिक बढ़ जाती है, इसलिए सीमाएं (1/2), (2/2), (3/2), (4/2), आदि हैं। ।
मेलमोकब

हां, यह विचार है जो SNDD के लिए किसी भी मूल्य का प्रमाण देता है।
Arnt Veenstra

1

क्लोजर - 185 वर्ण

शायद आगे अनुकूलित किया जा सकता है, लेकिन यहाँ जाता है:

(fn[A,B]((first(sort(for[r[range]n(r A(inc B))s[(str n)]l[(count s)]][(/(count(filter #(=(int%)(max 1%))(for[b(r(inc l))a(r b)](Math/sqrt(Integer/parseInt(subs s a b))))))(- l))n])))1))

दो मापदंडों के साथ एक फ़ंक्शन के रूप में उपयोग किया जाता है:

(crazy-function-as-above 14000 15000)
=> 14441

1

जेली , 21 बाइट्स, भाषा चुनौती चुनौती देती है

DµẆ1ị$ÐfḌƲS÷L
rµÇÐṀḢ

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

व्याख्या

हेल्पर फ़ंक्शन (इसके इनपुट की अंक घनत्व की गणना करता है):

DµẆ1ị$ÐfḌƲS÷L
Dµ              Default argument: the input's decimal representation
  Ẇ             All substrings of {the decimal representation}
      Ðf        Keep only those where
   1ị$          the first digit is truthy (i.e. not 0)
        Ḍ       Convert from decimal back to an integer
         Ʋ     Check each of those integers to see if it's square
           S    Sum (i.e. add 1 for each square, 0 for each nonsquare)
            ÷L  Divide by the length of {the decimal representation}

मुख्य कार्यक्रम:

rµÇÐṀḢ
rµ              Range from the first input to the second input
  ÇÐṀ           Find values that maximize the helper function
     Ḣ          Choose the first (i.e. smallest)

इस कार्यक्रम के बिना यकीनन अधिक दिलचस्प है - इस तरह, यह केवल एक के बजाय सभी अधिकतम-घनत्व संख्या देता है - लेकिन मैंने इसे विनिर्देश के अनुपालन के लिए जोड़ा।

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