ผลรวมของจำนวนเฉพาะระหว่างช่วงที่กำหนด


27

เขียนรหัสที่สั้นที่สุดสำหรับการหาผลรวมของช่วงเวลาระหว่างaและb(รวม)

อินพุต

  1. aและbสามารถนำมาจากบรรทัดคำสั่งหรือ stdin (ช่องว่างแยก)
  2. สมมติว่า1 <= a <= b <=10 8

ผลลัพธ์ เพียงพิมพ์ผลรวมด้วยอักขระบรรทัดใหม่

คะแนนโบนัส

  1. หากโปรแกรมยอมรับหลายช่วง (พิมพ์หนึ่งผลรวมในแต่ละบรรทัด) คุณจะได้รับคะแนนพิเศษ :)

ขีด จำกัด สูงสุดนั้นใหญ่เกินไปที่จะอนุญาตวิธีแก้ปัญหาที่น่าสนใจมากมาย (อย่างน้อยพวกเขาจะต้องทำให้เสร็จในเวลาที่เหมาะสม)
hallvabo

@ Hallvabo คุณพบว่าโซลูชันที่ไม่มีประสิทธิภาพน่าสนใจใช่ไหม
Matthew อ่าน

@ hallvabo ไม่เป็นไร ฉันไม่คิดว่าใครจะนึกถึงทางออกที่ไม่มีประสิทธิภาพ หากวัตถุของคนอื่นฉันจะมีความสุขมากกว่าที่จะลดวงเงิน
st0le

เพิ่งสร้างและรันโปรแกรมรุ่นที่ไม่ได้รับการปรับให้เหมาะสมหรือกระชับที่สุดใน C # โดยใช้ 1 ถึง 10 ^ 8 สมมติว่าอัลกอริทึมของฉันถูกต้องมันทำงานได้ต่ำกว่า 1m30s และไม่ล้นจากระยะเวลานาน ดูเหมือนจะเป็นขีด จำกัด ที่ดีสำหรับฉัน!
Nellius

การตรวจสอบที่ง่ายอย่างรวดเร็ว: ผลรวมของช่วงเวลาระหว่าง 1 ถึง 100 = 1,060
Nellius

คำตอบ:


15

J, 41 32 19 ตัวอักษร:

ปรับปรุง

(ตะแกรงง่าย)

g=:+/@(*1&p:)@-.&i.

เช่น

100 g 1
1060
250000x g 48
2623030823

ก่อน

h=:3 :'+/p:i.(_1 p:>:y)'
f=:-&h<:

เช่น:

100 f 1
1060

11

Mathematica 7 (31 ตัวอักษรเป็นข้อความธรรมดา)

หากอนุญาตให้ใช้โซลูชัน PARI / GP ดังนั้น:

Plus@@Select[Range[a,b],PrimeQ]

ประเด็นของคุณคืออะไร? PARI / GP และ Mathematica เป็นภาษาโปรแกรมที่ดี
Eelvex

@Eevenx ไม่พวกเขาทำผิดกฎข้อหนึ่งของกอล์ฟ: ใช้ฟังก์ชั่นระดับสูงเฉพาะในตัว
Nakilon

ฉันไม่คิดว่าจะมีกฎเช่นนี้ มันยังคงเป็นเรื่องเปิดเมื่อใช้ฟังก์ชั่นระดับสูง ดูตัวอย่าง คำถามเมตานี้
Eelvex

1
28 Range[a,b]~Select~PrimeQ//Trตัวอักษร
chyanog


5

C # (294 ตัวอักษร):

using System;class P{static void Main(){int a=int.Parse(Console.ReadLine()),b=int.Parse(Console.ReadLine());long t=0;for(int i=a;i<=b;i++)if(p(i))t+=i;Console.WriteLine(t);}static bool p(int n){if((n%2<1&&n!=2)||n<2)return 0>1;for(int i=3;i<=Math.Sqrt(n);i+=2)if(n%i==0)return 0>1;return 1>0;}}

คุณสามารถทำให้ทั้งหมดของคุณints และบันทึกตัวอักษรไม่กี่:long long a=...,b=...,t=0,i=a;for(;i<=b;i++)ทำให้ได้ตัวอักษร 288 ตัว นอกจากนี้คุณยังสามารถที่จะให้pกลับมาเป็นเวลานานและเพิ่งกลับมาอย่างใดอย่างหนึ่ง0หรือและลดห่วงไปn t+=p(i)277 ตัวอักษรแล้ว
Joey

5

PARI / GP (44 ตัวอักษร)

sum(x=nextprime(a),precprime(b),x*isprime(x))

6
ไม่ควรลงคะแนนเสียงให้เหตุผลสำหรับ -1 ของพวกเขา?
Eelvex

Downvote อาจเป็นเพราะใช้บิวด์อิน
mbomb007

4

BASH Shell

47 ตัวอักษร

seq 1 100|factor|awk 'NF==2{s+=$2}END{print s}'

แก้ไข: เพิ่งรับรู้ผลรวมล้นและถูกบังคับเป็นสองเท่า

52 50 ตัวละคร

นี่เป็นวิธีแก้ปัญหาที่ใช้เวลานานกว่าเล็กน้อย แต่จัดการได้ดีเช่นกัน

seq 1 100|factor|awk NF==2{print\$2}|paste -sd+|bc

TR สั้นกว่าแปะและคุณสามารถลบเครื่องหมายคำพูดเดี่ยว (ยกเว้น$)
Nabb

@Nabb จะแก้ไขทันทีที่ฉันได้รับในกล่อง * ระวังหรือคุณสามารถทำเกียรตินิยม
st0le

@Nabb ไม่สามารถใช้งานได้trเพิ่มเครื่องหมาย '+' ท้ายที่สุดการแก้ไขจะใช้เวลามากกว่าตัวอักษร
st0le

อ่าพลาดแล้ว แม้ว่าฉันคิดว่าคุณยังคงสามารถเปลี่ยนเป็นawk NF==2{print\$2}บันทึกไบต์บนโซลูชันที่ยาวกว่าได้ (เราจะไม่เรียกใช้การขยายรั้งโดยไม่ตั้งใจเพราะไม่มีเครื่องหมายจุลภาคหรือ..s)
Nabb

@Nabb คุณพูดถูก เสร็จสิ้น :)
st0le

4

C #, 183 ตัวอักษร

using System;class P{static void Main(string[] a){long s=0,i=Math.Max(int.Parse(a[0]),2),j;for(;i<=int.Parse(a[1]);s+=i++)for(j=2;j<i;)if(i%j++==0){s-=i;break;}Console.WriteLine(s);}}

นี่จะสั้นกว่านี้มากหากไม่ต้องตรวจสอบ 1 หรือถ้ามีวิธีที่ดีกว่าใน ... ในรูปแบบที่อ่านได้มากขึ้น:

using System;
class P 
{ 
    static void Main(string[] a) 
    { 
        long s = 0,
             i = Math.Max(int.Parse(a[0]),2),
             j;

        for (; i <= int.Parse(a[1]);s+=i++)
            for (j = 2; j < i; )
                if (i % j++ == 0)
                {
                    s -= i;
                    break;
                }

        Console.WriteLine(s); 
    }
}

ฉันชอบอันนี้สั้น แต่ฉันสงสัยว่ามันจะไม่มีประสิทธิภาพเมื่อคำนวณได้ถึง 10 ^ 8!
Nellius

จริง แต่ประสิทธิภาพไม่ได้อยู่ในกฎ!
Nick Larsen

คุณรู้ว่าคอมไพเลอร์เริ่มต้นที่ตัวเลขเป็น 0 ใช่มั้ย นั่นจะช่วยให้คุณประหยัดอีกสองสามตัวอักษร
jcolebrand

ให้ข้อผิดพลาดเมื่อคอมไพล์โดยไม่มีมัน
Nick Larsen

... เพราะมันไม่เคยได้รับมอบหมายก่อนที่มันจะถูกนำมาใช้ (ผ่านs -= i;เพราะ thats เพียงน้ำตาลประโยคสำหรับs = s - i;ซึ่งพยายามที่จะเข้าถึงsก่อนที่จะตั้ง)
นิคเสน

3

Haskell (80)

c=u[2..];u(p:xs)=p:u[x|x<-xs,x`mod`p>0];s a b=(sum.filter(>=a).takeWhile(<=b))c

s 1 100 == 1060


นี่คือรหัสกอล์ฟ! ทำไมคุณถึงใช้ชื่อยาว ๆ เพื่อสิ่งของของคุณ?
FUZxxl

4
มันยากที่จะหาชื่อที่สั้นกว่า c, u, s ... ที่เหลือเป็นห้องสมุดมาตรฐานภาษา
JB

3

Ruby 1.9, 63 chars

require'prime';p=->a,b{Prime.each(b).select{|x|x>a}.inject(:+)}

ใช้แบบนี้

p[1,100] #=> 1060

การใช้Primeชั้นเรียนรู้สึกเหมือนโกง แต่เนื่องจากโซลูชัน Mathematica ใช้ฟังก์ชั่นสำคัญในตัว ...


3

Perl, 62 ตัวอักษร

<>=~/\d+/;map$s+=$_*(1x$_)!~/^1$|(^11+)\1+$/,$&..$';print$s,$/

อันนี้ใช้เลขเอกสิทธิ์ regex


3

งานปกติ (Python 3): 95 ตัวอักษร

a,b=map(int,input().split())
r=range
print(sum(1%i*all(i%j for j in r(2,i))*i for i in r(a,b+1)))

งานโบนัส (Python 3): 119 chars

L=iter(map(int,input().split()))
r=range
for a,b in zip(L,L):print(sum(1%i*all(i%j for j in r(2,i))*i for i in r(a,b+1)))

3

Pari / GP (24 ตัวอักษร)

s=0;forprime(i=a,b,s+=i)

เช่นเดียวกับการแก้ปัญหาอื่น ๆ บางอย่างนี้ไม่ได้เคร่งครัดตอบสนองความต้องการที่เป็นaและbไม่ได้อ่านจาก stdin หรือบรรทัดคำสั่ง ฉันคิดว่ามันเป็นทางเลือกที่ดีในการแก้ปัญหา Pari / GP และ Mathematica อื่น ๆ


1
+1: นี่คือวิธีที่ฉันทำจริง ๆ แม้ว่าจะไม่เล่นกอล์ฟก็ตาม
ชาร์ลส์

2

เสียงกระเพื่อมสามัญ: (107 ตัวอักษร)

(flet((p(i)(loop for j from 2 below i never (= (mod i j) 0))))(loop for x from(read)to(read)when(p x)sum x))

ใช้งานได้เฉพาะกับจุดเริ่มต้น> = 1


2

APL (25 ตัวอักษร)

+/((R≥⎕)^~R∊R∘.×R)/R←1↓⍳⎕

นี่คือการดัดแปลงของสำนวนที่รู้จักกันดี (ดูหน้านี้สำหรับคำอธิบาย) เพื่อสร้างรายการของช่วงเวลาใน APL

ตัวอย่าง:

      +/((R≥⎕)^~R∊R∘.×R)/R←1↓⍳⎕
⎕:
      100
⎕:
      1
1060

2

ปัจจัย -> 98

:: s ( a b -- n )
:: i ( n -- ? )
n 1 - 2 [a,b] [ n swap mod 0 > ] all? ;
a b [a,b] [ i ] filter sum ;

เอาท์พุท:

( scratchpad ) 100 1000 s

--- Data stack:
75067

2

R, 57 ตัวอักษร

a=scan();b=a[1]:a[2];sum(b[rowSums(!outer(b,b,`%%`))==2])

n=2จำเป็นต้องระบุscan()หรือไม่? หากอินพุตเป็นมาตรฐานมีปัญหาในการข้ามอาร์กิวเมนต์และสมมติว่าต้องการ <enter> พิเศษหรือไม่?
Gaffi

1
ไม่จริงคุณพูดถูกถ้าไม่มี มันเป็นอย่างหมดจดเพื่อเหตุผลด้านความงาม (ตั้งแต่ฉันรู้รหัสของฉันไม่ได้อยู่แล้วที่สั้นที่สุด :))
plannapus

ดี +1 จากฉันเหมือนกันเพราะมันไม่ได้ยาวที่สุดแน่นอน
Gaffi

2

Japtap , 7 ไบต์

òV fj x

ลองที่นี่


ยินดีต้อนรับสู่ Japt :)
Shaggy

@Shaggy ฉันพยายามค้นหา "ช่วงไพร์ม" ใน Japt แต่แล้วก็ตัดสินใจยอมรับความท้าทาย: p
Erik the Outgolfer

เมื่อพิจารณาถึงความท้าทายที่เกี่ยวข้องกับจำนวนเฉพาะทางลัดสำหรับการใช้งานfj<space>อาจเป็นประโยชน์
Shaggy

1

Perl, 103 ตัวอักษร

while(<>){($a,$b)=split/ /;for($a..$b){next if$_==1;for$n(2..$_-1){$_=0if$_%$n==0}$t+=$_;}print"$t\n";}

มันจะยอมรับหลายช่องว่างคั่นบรรทัดและให้คำตอบสำหรับแต่ละ: D


1

ใน Q (95):

d:{sum s:{if[2=x;:x];if[1=x;:0];$[0=x mod 2;0;0=min x mod 2+til floor sqrt x;0;x]}each x+til y}

ตัวอย่างการใช้งาน:

q)d[1;100]
1060

1

C # 302

using System;namespace X{class B{static void Main(){long x=long.Parse(Console.ReadLine()),y=long.Parse(Console.ReadLine()),r=0;for(long i=x;i<=y;i++){if(I(i)){r+=i;}}Console.WriteLine(r);}static bool I(long n){bool b=true;if(n==1){b=false;}for(long i=2;i<n;++i){if(n%i==0){b=false;break;}}return b;}}}

1

Mathematica , 27

กำหนดไว้ล่วงหน้าaและb:

a~Range~b~Select~PrimeQ//Tr

ในฐานะที่เป็นฟังก์ชั่น (เช่น 27):

Tr[Range@##~Select~PrimeQ]&

1

R (85 ตัวอักษร)

x=scan(nmax=2);sum(sapply(x[1]:x[2],function(n)if(n==2||all(n %% 2:(n-1)))n else 0))

ไม่มีประสิทธิภาพมาก! ฉันค่อนข้างแน่ใจว่ามันต้องใช้เวลา O (n ^ 2) มันอาจให้คำเตือนเกี่ยวกับการบีบบังคับคู่กับตรรกะ

Deobfuscated:

x <- scan(nmax=2)
start <- x[1]
end <- x[2]

#this function returns n if n is prime, otherwise it returns 0.
return.prime <- function(n) {
  # if n is 2, n is prime. Otherwise, if, for each number y between 2 and n, n mod y is 0, then n must be prime
  is.prime <- n==2 || all(n%% 2:(n-1))
  if (is.prime)
    n
  else
    0
} 
primes <- sapply(start:end, return.prime)
sum(primes)

1

Python 3.1 (153 ตัวอักษร):

from sys import*
p=[]
for i in range(int(argv[1]),int(argv[2])):
 r=1
 for j in range(2,int(argv[2])):
  if i%j==0and i!=j:r=0
 if r:p+=[i]
print(sum(p))

1. from sys import*2. r=True-> r=1(และตามลำดับ0สำหรับFalse) 3. if i%j==0and i!=j:r=04. if r:p+=[i]5. print(sum(p))(แทนที่ 4 บรรทัดสุดท้าย)
seequ

คุณสามารถใช้input()ให้สั้นลง นอกจากนี้คุณสามารถใช้if i%j<1andแทนได้หรือไม่
mbomb007

1

GolfScript, 27 24 ไบต์

~,>{:x,{)x\%!},,2=},{+}*

นี้จะตามออก @ w0lf เป็นอัลกอริทึมจำนวนเฉพาะ



0

Python: 110 ตัวอักษร

l,h=map(int,raw_input().split())
print sum(filter(lambda p:p!=1 and all(p%i for i in range(2,p)),range(l,h)))

สิ่งนี้ไม่รวม
jamylak

0

Python, 133

เวทมนตร์เล็กน้อย:

x,y=map(int,raw_input().split())
y+=1
a=range(y)
print sum(i for i in[[i for a[::i]in[([0]*y)[::i]]][0]for i in a[2:]if a[i]]if i>=x)

-1 (ฉันยังมีตัวแทนไม่เพียงพอที่จะลงคะแนน) นี่ไม่ถูกต้องใน Python 2 หรือ 3 คุณไม่สามารถคาดหวังว่าการป้อนข้อมูลจะมีเครื่องหมายคำพูดสำหรับคุณได้อย่างสะดวก เปลี่ยนเป็น raw_input หรือใช้ python 3 plz
jamylak

คุณสามารถลบy+=1และใช้แทนrange(y+1)และ([0]*-~y)[::i]เพื่อบันทึกไบต์ (การลบบรรทัดใหม่) และการใช้ Python 3 จะช่วยให้คุณสามารถใช้งานได้input()ตราบใดที่คุณใส่วงเล็บprintแล้วจึงลบ 4 ไบต์ แต่เพิ่ม 1 คุ้มค่า
mbomb007

0

133 chars, Lua (ไม่มีฟังก์ชั่น is_prime ในตัว)

for i=m,n,1 do
if i%2~=0 and i%3~=0 and i%5~=0 and i%7~=0 and i%11~=0 then
s=s+1
end
end
print(s)

นี่คือตัวอย่างที่ผมเพิ่มบรรทัด "พิมพ์ (i)" เพื่อแสดงช่วงเวลาทั้งหมดที่พบและผลรวมในตอนท้ายของพวกเขาที่: http://codepad.org/afUvYHnm


“ a และ b สามารถนำมาจาก command line หรือ stdin” ในสองวิธีใดที่ตัวเลขเหล่านี้สามารถส่งผ่านไปยังโค้ดของคุณได้?
จัดการ

1
ตามที่กล่าวมานี้ 13 (สิ่งใด ๆ เหนือมัน) ไม่ใช่จำนวนเฉพาะ
st0le

@ st0le ตามตรรกะ 13 เป็น "นายก" ( แต่เช่น 2 ไม่ได้) - บนมืออื่น ๆ 13 * 13 = 169 คือ "สำคัญ" อีกครั้ง ...
ฮาวเวิร์ด


0

F # (141)

หนึ่งในสามของรหัสคือการแยกวิเคราะห์อินพุต

let[|a;b|]=System.Console.ReadLine().Split(' ')
{int a..int b}|>Seq.filter(fun n->n>1&&Seq.forall((%)n>>(<>)0){2..n-1})|>Seq.sum|>printfn"%A"
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.