ค้นหาหมายเลข semiperfect ดั้งเดิม


17

หมายเลขเซมิเพอร์เฟค

หมายเลข semiperfect / pseudoperfect เป็นจำนวนเต็มเท่ากับผลรวมของส่วนหนึ่งส่วนหรือทั้งหมดของตัวหาร (ยกเว้นตัวเอง) ตัวเลขที่เท่ากับผลรวมของตัวหารทั้งหมดนั้นสมบูรณ์แบบ

Divisors of 6 : 1,2,3
      6 = 1+2+3 -> semiperfect (perfect)
Divisors of 28 : 1,2,4,7,14
      28 = 14+7+4+2+1 -> semiperfect (perfect)
Divisors of 40 : 1,2,4,5,8,10,20
      40 = 1+4+5+10+20 or 2+8+10+20 -> semiperfect

ดั้งเดิม

หมายเลข semiperfect ดั้งเดิมคือหมายเลข semiperfect ที่ไม่มีตัวหาร semiperfect (ยกเว้นตัวมันเอง :))

Divisors of 6 : 1,2,3
      6  = 1+2+3 -> primitive
Divisors of 12 : 1,2,3,4,6
      12 = 2+4+6 -> semiperfect

จากการอ้างอิงโปรดใช้ OEIS ซีรี่ย์A006036สำหรับหมายเลขเซมิเพอร์ไพเพอร์ดั้งเดิมและA005835สำหรับเซมิเพอร์เซ

เป้าหมาย

เขียนโปรแกรมหรือฟังก์ชั่นในภาษาใดก็ได้ มันจะใช้เป็นตัวเลขป้อน n เป็นพารามิเตอร์ฟังก์ชั่นหรือจาก STDIN / ทางเลือกที่ใกล้เคียงที่สุดของภาษาของคุณและจะส่งออกตัวเลขกึ่งสมบูรณ์แบบดั้งเดิมทั้งหมดจาก 1 ถึง n (รวม)

เอาต์พุตต้องถูกจัดรูปแบบโดย6[separator]20[separator]28[separator]88...ที่ [separator] เป็นบรรทัดใหม่เว้นวรรคหรือเครื่องหมายจุลภาค จะต้องไม่มี [ตัวคั่น] เริ่มต้นหรือตัวลงท้าย

แก้ไข: คุณสามารถเว้นบรรทัดขึ้นบรรทัดใหม่ได้

ตัวอย่าง

อินพุต:

5

ผลลัพธ์:

อินพุต:

20

ผลลัพธ์:

6
20

อินพุต:

100

ผลลัพธ์:

6 20 28 88

เกณฑ์การให้คะแนน

นี่คือโค้ดกอล์ฟดังนั้นโค้ดที่สั้นที่สุดเป็นไบต์จะเป็นผู้ชนะ

อย่าพยายามหลอกเราด้วยช่องโหว่โปรด :)

ฉันดีใจที่คุณสามารถอธิบายรหัสกอล์ฟของคุณได้เมื่อคุณคิดว่าคุณเล่นกอล์ฟเสร็จแล้ว!

เนื่องจากความท้าทายนี้มีคำตอบที่ดีอยู่แล้วและเงียบลงเรื่อย ๆ ฉันจะยุติเรื่องนี้ ผู้ชนะการแข่งขันรหัสนี้จะได้รับการตัดสินในวันจันทร์ที่ 29, 00:00 GMT ทำได้ดีสำหรับคุณทุกคนที่ตอบแล้วและขอให้โชคดีสำหรับผู้ที่จะพยายามเอาชนะพวกเขา :)

คำตอบ:


8

Pyth, 28 27 ไบต์

VQI}KhNsMyJf!%KTSNI!@JYeaYK

1 ไบต์ต้องขอบคุณ @Jakube

สาธิต.

VQI}KhNsMyJf!%KTSNI!@JYeaYK
                                Implicit:
                                Y = []
                                Q = eval(input())
VQ                              for N in range(Q):
    KhN                         K = N+1
           f    SN              filter T over range(1, N)
            !%KT                the logical not of K%T.
                                This is the list of divisors of K.
          J                     Store the list in J.
         y                      Create all of its subsets.
       sM                       Map each subset to its sum.
  I}K                           If K is in that list: (If K is semiperfect)
                  I!@JY         If the intersection of J (the divisors)
                                and Y (the list of primitive semiperfect numbers)
                                is empty:
                        aYK     Append K to Y
                       e        And print its last element, K.

@AlexA ขอบคุณ! มันเป็นสิ่งจำเป็นที่จะผนวกKการYที่จะสร้างYซึ่งเป็นสิ่งจำเป็นอื่น ๆ แต่ผมจะทำพิมพ์แยกกันเช่นกับแทนaYKK eaYKอย่างไรก็ตามมันเป็น 4 ไบต์ทั้งสองทาง
isaacg

3

จูเลีย, 161 149 ไบต์

n->(S(m)=!isempty(filter(i->i==unique(i)&&length(i)>1&&all(j->m%j<1,i),partitions(m)));for i=2:n S(i)&&!any(S,filter(k->i%k<1,1:i-1))&&println(i)end)

สิ่งนี้จะสร้างฟังก์ชั่นที่ไม่มีชื่อที่รับจำนวนเต็มเป็นอินพุตและพิมพ์ตัวเลขไปที่ STDOUT คั่นด้วยบรรทัดใหม่ f=n->...เรียกว่าให้มันชื่อเช่น

คำอธิบาย Ungolfed +:

# Define a function that determines whether the input is semiperfect
# (In the submission, this is defined as a named inline function within the
# primary function. I've separated it here for clarity.)

function S(m)
    # Get all integer arrays which sum to m
    p = partitions(m)

    # Filter the partitions to subsets of the divisors of m
    d = filter(i -> i == unique(i) && length(i) > 1 && all(j -> m % j == 0, i), p)

    # If d is nonempty, the input is semiperfect
    !isempty(d)
end

# The main function

function f(n)
    # Loop through all integers from 2 to n
    for i = 2:n
        # Determine whether i is semiperfect
        if S(i)
            # If no divisors of i are semiperfect, print i
            !any(S, filter(k -> i % k == 0, 1:i-1) && println(i)
        end
    end
end

ตัวอย่าง:

julia> f(5)

julia> f(40)
6
20
28

3

JavaScript ( ES6 ) 172

เรียกใช้ตัวอย่างข้อมูลด้านล่างเพื่อทดสอบ

f=
v=>eval("for(n=h=[];n++<v;!t*i&&n>1?h[n]=1:0){for(r=[l=i=t=1];++i<n;)n%i||(h[i]?t=0:l=r.push(i));for(i=0;t&&++i<1<<l;)r.map(v=>i&(m+=m)?t-=v:0,t=n,m=.5)}''+Object.keys(h)")


// Less golfed

ff=v=>
{
   h=[]; // hashtable with numbers found so far

   for (n=1; n <= v; n++)
   {
      r=[1],l=1; // r is the list of divisors, l is the length of this list
      t=1; // used as a flag, will become 0 if a divisor is in h
      for(i=2; i<n; i++)
      {
         if (n%i == 0)
            if (h[i])
               t = 0; // found a divisor in h, n is not primitive
            else
               l = r.push(i); // add divisor to r and adjust l
      }
      if (t != 0) // this 'if' is merged with the for below in golfed code
      { 
         // try all the sums, use a bit mask to find combinations
         for(i = 1; t != 0 && i < 1<<l; i++)
         {
            t = n; // start with n and subtract, if ok result will be 0 
            m = 0.5; // start with mask 1/2 (nice that in Javascript we can mix int and floats)
            r.forEach( v=> i & (m+=m) ? t -= v : 0);
         }
         if (t == 0 && n > 1) h[n] = 1; // add n to the hashmap (the value can be anything)
      }
   }
   // the hashmap keys list is the result
   return '' + Object.keys(h) // convert to string, adding commas
}

(test=()=> O.textContent=f(+I.value))();
<input id=I type=number oninput="test()" value=999><pre id=O></pre>


@ JörgHülsermannเสร็จแล้วขอบคุณที่สังเกต
edc65

2

CJam, 54 ไบต์

วิธีแก้ปัญหานี้ให้ความรู้สึกอึดอัดเล็กน้อย แต่เนื่องจากมีคำตอบไม่กี่ข้อและไม่มีใน CJam ฉันคิดว่าฉันจะโพสต์ต่อไป:

Lli),2>{_N,1>{N\%!},_@&!\_,2,m*\f{.*:+}N#)e&{N+}&}fNS*

ส่วนที่ดีของการเพิ่มขึ้นของโซลูชัน Pyth ที่โพสต์นั้นมาจากข้อเท็จจริงที่ว่าเท่าที่ฉันจะหาได้ CJam ไม่มีตัวดำเนินการเพื่อระบุชุดย่อยทั้งหมดของชุด ดังนั้นจึงต้องใช้เวลาดำเนินการบางอย่างเพื่อให้เสร็จสมบูรณ์กับผู้ให้บริการ แน่นอนถ้ามีโอเปอเรเตอร์ธรรมดาที่ฉันพลาดไปฉันจะดูโง่ ๆ :)

คำอธิบาย:

L     Start stack with empty list that will become list of solutions.
li    Get input N and convert to int.
),2>  Build list of candidate solutions [2 .. N].
{     Start for loop over all candidate solutions.
_     Copy list of previous solutions, needed later to check for candidate being primitive.
N,1>  Build list of possible divisors [1 .. N-1].
{N\%!},  Filter list to only contain actual divisors of N.
_     Check if one of divisors is a previous solution. Start by copying divisor list.
@     Pull copy of list with previous solutions to top of stack
&!    Intersect the two lists, and check the result for empty. Will be used later.
\     Swap top two elements, getting divisor list back to top.
_,    Get length of divisor list.
2,    Put [0 1] on top of stack.
m*    Cartesian power. Creates all 0/1 sequences with same length as divisor list.
\     Swap with divisor list.
f{.*:+}  Calculate element by element product of all 0/1 sequences with divisors,
         and sum up the values (i.e. dot products of 0/1 sequences with divisors).
         The result is an array with all possible divisor sums.
N#)  Find N in list of divisor sums, and covert to truth value.
e&   Logical and with earlier result from primitive test.
{N+}&  Add N to list of solutions if result is true.
}fN  Phew! We finally made it to the end of the for loop, and have a list of solutions.
S*   Join the list of solutions with spaces in between.

ลองออนไลน์


2

PHP, 263 ไบต์

function m($a,$n){for($t=1,$b=2**count($a);--$b*$t;$t*=$r!=$n,$r=0)foreach($a as$k=>$v)$r+=($b>>$k&1)*$v;return$t;}for($o=[];$i++<$argn;m($d,$i)?:$o=array_merge($o,range($r[]=$i,3*$argn,$i)))for($d=[],$n=$i;--$n*!in_array($i,$o);)$i%$n?:$d[]=$n;echo join(",",$r);

ลองออนไลน์!

ขยาย

function m($a,$n){ 
  for($t=1,$b=2**count($a);--$b*$t;$t*=$r!=$n,$r=0) #loop through bitmasks
    foreach($a as$k=>$v)$r+=($b>>$k&1)*$v; # loop through divisor array
  return$t;} # returns false for semiperfect numbers 
for($o=[];$i++<$argn;
m($d,$i)?
  :$o=array_merge($o,range($r[]=$i,3*$argn,$i))) # Make the result array and the array of multiples of the result array 
  for($d=[],$n=$i;--$n*!in_array($i,$o);) # check if integer is not in multiples array
    $i%$n?:$d[]=$n; # make divisor array
echo join(",",$r); #Output

1

เยลลี่ , 22 ไบต์

ÆDṖŒPS€i
ÆDÇ€TL’
RÇÐḟY

ลองออนไลน์!

คำอธิบาย

ÆDṖŒPS€i - helper function to check if input is a semiperfect number
ÆD       - list of divisors of input
  Ṗ      - except for the last one (the input)
   ŒP    - power set = every possible subset of divisors
     S€  - sum of each subset
       i - return truthy iff input is one of these

ÆDÇ€TL’ - helper function to check if input is a primitive semiperfect number
ÆD       - list of divisors of input
  ǀ     - replace each with if they are a semiperfect number, based on 
           the above helper function. If input is a primitive semiperfect 
           number, we get something like [0,0,0,0,0,94]. 
    T    - get all truthy values.
     L’  - return falsy iff there is only one truthy value

RÇÐḟY    - main link
R        - Range[input]
 ÇÐḟ     - Filter out those elements which are not primitive semiperfect
           numbers, based on the helper function
    Y    - join by newlines.
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.