N अजीब संख्या प्रिंट करें


12

एक अजीब संख्या एक संख्या है जो उचित विभाजक का योग संख्या से अधिक है और उस संख्या के लिए उचित भाजक का कोई सबसेट नहीं है।

उदाहरण:

70 एक अजीब संख्या है, क्योंकि इसके उचित भाजक (1, 2, 5, 7, 10, 14, और 35) का योग 74 है, जो कि 70 से अधिक है, और इन संख्याओं का कोई जोड़ 70 तक नहीं है।

18 एक अजीब संख्या नहीं है क्योंकि इसके उचित विभाजक (1, 2, 3, 4, 6, 9) योग 25 तक हैं, जो 18 से अधिक है, लेकिन 3, 6 और 9 योग से 18 है।

आपका काम सबसे छोटा प्रोग्राम लिखना है जो किसी भी नंबर n में std-in के माध्यम से इनपुट करता है और एक फ़ाइल या std-out से पहले n अजीब संख्या में न्यूलाइन सेपरेशन के साथ गणना और प्रिंट करता है। उत्तरों की कोई हार्ड कोडिंग की अनुमति नहीं है (शुरुआत में इसे निर्दिष्ट नहीं करने के लिए खेद है)।

अधिक उदाहरणों के लिए, इस पृष्ठ को देखें: http://mathworld.wolfram.com/WeirdNumber.html


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

जवाबों:


2

गणितज्ञ 99 94 87

रिक्त स्थान की आवश्यकता नहीं है। धीरे !:

j = i = 0;
While[j<#, i++; If[Union@Sign[Tr /@ Subsets@Most@Divisors@i-i]=={-1, 1}, j++; Print@i]]&

कुछ वर्णों की कीमत पर यह एक तेज संस्करण है जो केवल संख्याओं की जाँच करता है और 6उस के गुणक कभी भी अजीब नहीं होते हैं:

j = i = 0;
While[j < #, 
      i += 2; If[Mod[i, 6] != 0 && Union@Sign[Tr /@ Subsets@Most@Divisors@i - i] == {-1, 1}, 
                 j++; Print@i]] &@3

यह अभी भी किसी भी उपयोगी उद्देश्य के लिए बहुत धीमा है। पहले दो को कुछ सेकंड में ढूँढता है लेकिन डिवाइडरों की संख्या बढ़ने के साथ धीमी और धीमी हो जाती है।


मैं इस तथ्य का फायदा उठाते हुए एक समान समाधान के साथ कल्पना कर रहा था कि अजीब संख्याएं छद्म संक्रामक नहीं हैं, लेकिन आप इसे बहुत गोल्फर की तुलना में मैं अब तक प्रबंधित कर रहा था। बहुत अच्छा!
जोनाथन वान मैट्रे

@JonathanVanMatre आपका धन्यवाद :)
डॉ। बेलिसरियस

4

हास्केल - 129

मुझे यकीन है कि यहां गोल्फ बहुत है, लेकिन चूंकि प्रतियोगिता कम लगती है इसलिए मैं इसे फेंक दूंगा।

हालांकि इसे चलाने की कोशिश मत करो, मैं केवल दो पहले तत्वों का इंतजार करने में कामयाब रहा, तीसरा मिनट लेना शुरू कर देगा।

(%)=filter
w n=take n$e%[1..]
e x=let d=((==0).mod x)%[1..x-1]in sum d>x&&all((/=x).sum)(i d)
i[]=[[]]
i(y:z)=map(y:)(i z)++(i z)

1
हास्केल में सेज में यह मेरे लिए दूसरी बार बेहतर है, लानत है: D
यो '

2

पायथन 2.7 (255 बाइट्स)

import itertools as t
a=int(raw_input())
n=1
while a>0:
    d=[i for i in range(1,n/2+1) if not n%i]
    if all([n not in map(sum,t.combinations(d,i)) for i in range(len(d))]+[sum(d)>n]):
        print n
        a-=1
    n+=1

1

PHP, 267 बाइट्स

$n=$x=0;while($n<$argv[1]){$x++;for($i=1,$s=0,$d=array();$i<$x;$i++){if($x%$i){continue;}$s+=$i;$d[]=$i;}if($s<$x){continue;}$t=pow(2,$m=count($d));for($i=0;$i<$t;$i++){for($j=0,$s=0;$j<$m;$j++){if(pow(2,$j)&$i){$s+=$d[$j];}}if($s==$x){continue 2;}}$n++;print"$x\n";}

और यहाँ मूल स्रोत कोड है:

$n = 0;
$x = 0;

while ($n < $argv[1]) {
    $x++;

    for ($i = 1, $sum = 0, $divisors = array(); $i < $x; $i++) {
        if ($x % $i) {
            continue;
        }

        $sum += $i;
        $divisors[] = $i;
    }

    if ($sum < $x) {
        continue;
    }

    $num = count($divisors);
    $total = pow(2, $num);

    for ($i = 0; $i < $total; $i++) {  
        for ($j = 0, $sum = 0; $j < $num; $j++) { 
            if (pow(2, $j) & $i) {
                $sum += $divisors[$j];
            }
        }

        if ($sum == $x) {
            continue 2;
        }
    }

    print "$x\n";
}

आप ध्यान देंगे कि यह संख्याओं को आउटपुट करने में कुछ समय लेता है क्योंकि यह एक ब्रुट-फोर्स सत्यापन कर रहा है (आपको 70 सुंदर तेज प्राप्त करना चाहिए, हालांकि)।


1

आर, 164

r=0;x=1;n=scan();while(r<n){i=which(!x%%(2:x-1));if(sum(i)-1&&!any(unlist(lapply(2:sum(i|T),function(o)colSums(combn(i,o))==x)))&sum(i)>x){r=r+1;cat(x,"\n")};x=x+1}

अन-गोल्फ संस्करण:

r = 0
x = 1
n = scan()
while(r < n) {
  i = which(!x %% (2:x - 1))
  if( sum(i) - 1 &&
       !any(unlist(lapply(2:sum(i | T),
                          function(o) colSums(combn(i, o)) == x))) &
       sum(i) > x
     ){ r = r + 1
        cat(x, "\n")
  }
  x = x + 1
}

ब्रूट-फोर्स के कारण इसमें कुछ समय लगता है।


1

रूबी - 152

x=2;gets.to_i.times{x+=1 while((a=(1..x/2).find_all{|y|x%y==0}).reduce(:+)<=x||(1..a.size).any?{|b|a.combination(b).any?{|c|c.reduce(:+)==x}});p x;x+=1}

एक्टिव के साथ रूबी - 138

x=2;gets.to_i.times{x+=1 while((a=(1..x/2).find_all{|y|x%y==0}).sum<=x||(1..a.size).any?{|b|a.combination(b).any?{|c|c.sum==x}});p x;x+=1}

वास्तव में धीमा है और मुझे लगभग यकीन है कि अभी भी गोल्फ के लिए जगह है ...


1

स्मालटाक, 143

((1to:(Integer readFrom:Stdin))reject:[:n||d|d:=(1to:n//2)select:[:d|(n\\d)=0].d sum<n or:[(PowerSet for:d)contains:[:s|s sum=n]]])map:#printCR

इनपुट:

1000

उत्पादन:

70
836

1

सेजमैथ: 143 131 बाइट्स

x=1
def w():
 l=x.divisors()
 return 2*x>=sum(l)or max(2*x==sum(i)for i in subsets(l))
while n:
 while w():x+=1
 print x;n-=1;x+=1

यह और भी अधिक गोल्फ नहीं है, कोड में गोल्फ वैसे भी बहुत ज्यादा नहीं है। सबसे बड़ी बात यह है कि आपको 2*x>=sum(l)पहले परीक्षण करना चाहिए , इससे बहुत अधिक गणना समय की बचत होगी। एक एहसास है कि है maxबूलियन्स पर है orदूसरी बात यह है कि w(x)है Falseअजीब नंबरों के लिए और Trueगैर अजीब नंबरों के लिए। Ungolfed संस्करण:

def w(x) :
 Divisors = x.divisors()
 return 2*x >= sum(Divisors) or max ( sum(SubS) == 2*x for SubS in subsets(Divisors) )

x=1

for k in xrange(n) :
 while w(x) : x += 1
 print x
 x += 1

1

सी ++ - 458

यह मेरा सब समाधान नहीं है क्योंकि मुझे एसओ से सबसेट की राशि की गणना में मदद के लिए पूछना था, लेकिन बाकी सब कुछ मेरा है:

#include<iostream>
#include<vector>
using namespace std;
#define v vector<int>
#define r return
#define c const_iterator
v x(int i){v d;for(int k=1;k<i;k++)if(i%k==0)d.push_back(k);r d;}bool u(v::c i,v::c e,int s){if(s==0)r 0;if(i==e)r 1;r u(i+1,e,s-*i)&u(i+1,e,s);}bool t(v&d,int i){bool b=u(d.begin(),d.end(),i);if(b)cout<<i<<endl;r b;}int main(){v d;int n;cin>>n;for(int i=2,j=0;j<n;i++){d=x(i);int l=0;for(int k=0;k<d.size();k++)l+=d[k];if(l>i)if(t(d,i))j++;}}

दीर्घ संस्करण:

#include<iostream>
#include<vector>
using namespace std;

vector<int> divisors(int i) {

    vector<int> divs;
    for(int k = 1; k < i; k++)
        if(i%k==0)
            divs.push_back(k);
    return divs;
}

bool u(vector<int>::const_iterator vi, vector<int>::const_iterator end, int s) {

    if(s == 0) return 0;
    if(vi == end) return 1;
    return u(vi + 1, end, s - *vi) & u(vi + 1, end, s);
}

bool t(vector<int>&d, int i) {

    bool b = u(d.begin(), d.end(), i);
    if(b) cout<< i << endl;
    return b;
}

int main() {

    vector<int> divs;
    int n;
    cin>>n;

    for(int i = 2, j = 0; j < n; i++) {
        divs = divisors(i);

        int sum_divs = 0;
        for(int k = 0; k < divs.size(); k++)
            sum_divs += divs[k];

        if(sum_divs > i)
            if(t(divs, i))
                j++;
    }
}

वर्तमान में इसने केवल पहले दो (70 और 836) की गणना की है। मैंने उसके बाद इसे मार दिया।


एक पठनीय संस्करण पोस्ट करना अच्छा होगा, खासकर जब से आप इसे एक-लाइनर के रूप में बनाते हैं;)
यो '

@tohecz ज़रूर, मुझे इसे संपादित करने दें।

@tohecz मैं कर रहा हूँ।

1

पर्ल, 173

मुझे एक और बेकार समाधान जोड़ें। यह समाधान इतना धीमा है कि यह पहले अजीब संख्या से कुछ भी आउटपुट नहीं कर सकता है। मैं कहता हूं कि यह यहां के सभी समाधानों में सबसे धीमा है।

$n=<>;$i=2;while($n){$b=qr/^(?=(.+)\1{2}$)((.+)(?=.*(?(2)(?=\2$)\3.+$|(?=\1$)\3.+$))(?=.*(?=\1$)\3+$))+/;$_='x'x3x$i;if(/$b/&&($+[0]>$i)&&!/$b\1{2}$/){print"$i\n";$n--}$i++}

डेमो

उसी कोड को जावा में लिखा गया है (जो मैं अधिक आरामदायक हूं) 2 अजीब संख्या (836) को भी नहीं पहचान सकता है, और मैंने पहले ही नंबर को सीधे चेकिंग विधि (हर नंबर की जांच और जांच करने के बजाय) कर दिया है।

इस समाधान का मूल regex में निहित है:

^(?=(.+)\1{2}$)((.+)(?=.*(?(2)(?=\2$)\3.+$|(?=\1$)\3.+$))(?=.*(?=\1$)\3+$))+

और स्ट्रिंग की स्थापना कैसे की जाती है जो हम जाँच रहे हैं।

स्ट्रिंग की लंबाई को उस संख्या से 3 गुना सेट किया गया है जिसे हम जाँच रहे हैं i: पहला 2 iकारकों के मिलान योग के लिए है और अंतिम 1 iयह जाँचने के लिए आरक्षित है कि क्या संख्या एक कारक है i

(?=(.+)\1{2}$) का उपयोग उस संख्या को पकड़ने के लिए किया जाता है जिसे हम जाँच रहे हैं।

((.+)(?=.*(?(2)(?=\2$)\3.+$|(?=\1$)\3.+$))(?=.*(?=\1$)\3+$))+संख्या के कारकों से मेल खाता है। बाद में पुनरावृत्ति पहले के चलने की तुलना में एक छोटे कारक से मेल खाएगी।

  • हम देख सकते हैं कि ये 2 भाग (.+)और (?=.*(?=\1$)\3+$)साथ में जाँची जा रही संख्या के एक कारक का चयन करते हैं।
  • (?=.*(?(2)(?=\2$)\3.+$|(?=\1$)\3.+$)) यह सुनिश्चित करता है कि चयनित कारक पहले पुनरावृत्ति में जाँच की जा रही संख्या से छोटा है, और बाद के पुनरावृत्तियों में पिछले कारक से छोटा है।

रेगेक्स संख्या के कई कारकों से मेल खाने की कोशिश करता है क्योंकि यह 2 की सीमा के भीतर हो सकता है i। लेकिन हम लाभांश के योग के वास्तविक मूल्य के बारे में परवाह नहीं करते हैं, हम केवल यह ध्यान रखते हैं कि क्या संख्या प्रचुर है।

फिर 2 रेगेक्स, जो कि \1{2}$जोड़ा के साथ पहला रेगेक्स है। परिणामस्वरूप, रेगेक्स सुनिश्चित करता है कि जाँच की जा रही संख्या के कुछ (कुछ) कारक स्वयं संख्या के बराबर हैं:

^(?=(.+)\1{2}$)((.+)(?=.*(?(2)(?=\2$)\3.+$|(?=\1$)\3.+$))(?=.*(?=\1$)\3+$))+\1{2}$

जोड़ा गया बाधा रिजेक्स इंजन को कारकों के सभी संभावित सबसेट पर एक पीछे की खोज करने का कारण बनेगा, इसलिए यह बेहद धीमा होने वाला है।


1

पर्ल, 176 174 बाइट्स

$n=<>;$i=9;X:while($n){@d=grep{!($i%$_)}1..$i-1;$l=0;map{$a=$_;$s=0;$s+=$d[$_]for grep{2**$_&$a}0..@d-1;$i++,next X if$s==$i;$l=1 if$s>$i}0..2**@d-1;$n--,print$i,$/if$l;$i++}

एसटीडीआईएन में अजीब संख्या की उम्मीद की जाती है और एसटीडीयूएसटी के लिए पाए गए नंबर मुद्रित होते हैं।

अनप्लग्ड संस्करण

#!/usr/bin/env perl
use strict;
$^W=1;

# read number from STDIN
my $n=<>;
# $i is the loop variable that is tested for weirdness
my $i=9; # better start point is 70, the smallest weird number
# $n is the count of numbers to find
X: while ($n) {
    # find divisors and put them in array @divisors
    my @divisors = grep{ !($i % $_) } 1 .. $i-1; # better: 1 .. int sqrt $i
    # $large remembers, if we have found a divisor sum greater than the number
    my $large = 0;
    # looping through all subsets. The subset of divisors is encoded as
    # bit mask for the divisors array.
    map {
        my $subset = $_;
        # calculate the sum for the current subset of divisors
        my $sum = 0;
        map { $sum += $divisors[$_] }
            grep { 2**$_ & $subset }
                0 .. @divisors-1;
        # try next number, if the current number is pseudoperfect
        $i++, next X if $sum == $i; # better: $i+=2 to skip even numbers
        $large = 1 if $sum > $i;
    } 0 .. 2**@divisors - 1;
    # print weird number, if we have found one
    $n--, print "$i\n" if $large;
    $i++; # better: $i+=2 to skip even numbers
}
__END__

सीमाएं

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