Suma liczb pierwszych między danym zakresem


27

Napisz najkrótszy kod do znalezienia sumy liczb pierwszych między ai b(włącznie).

Wkład

  1. ai bmoże być pobrany z wiersza poleceń lub standardowego wejścia (oddzielone spacją)
  2. Załóżmy 1 <= a <= b <=10 8

Wyjście Wystarczy wydrukować sumę ze znakiem nowej linii.

Punkty bonusowe

  1. Jeśli program akceptuje wiele zakresów (wydrukuj jedną sumę w każdej linii), otrzymasz dodatkowe punkty. :)

Górny limit jest zbyt duży, aby pozwolić na wiele interesujących rozwiązań (jeśli trzeba je ukończyć przynajmniej w rozsądnym czasie).
hallvabo

@hallvabo Czy uważasz, że nieefektywne rozwiązania są interesujące?
Mateusz

@hallvabo, w porządku. Nie sądzę, aby ktokolwiek miał na myśli nieefektywne rozwiązanie. Jeśli ktoś jest obiektem, z przyjemnością
obniżę

Właśnie stworzyłem i uruchomiłem niezbyt zoptymalizowaną lub zwięzłą wersję programu w języku C #, używając od 1 do 10 ^ 8. Zakładając, że mój algorytm jest poprawny, działał poniżej 1m30s i nie przepełniał się długo. Wydaje mi się to dobrą górną granicą!
Nellius

Szybka łatwa kontrola: suma liczb pierwszych od 1 do 100 = 1060.
Nellius

Odpowiedzi:


15

J, 41 32 19 znaków:

Aktualizacja

(proste sito)

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

na przykład

100 g 1
1060
250000x g 48
2623030823

Poprzedni

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

na przykład:

100 f 1
1060

11

Mathematica 7 (31 znaków w postaci zwykłego tekstu)

Jeśli dozwolone jest rozwiązanie PARI / GP, to:

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

O co ci chodzi? PARI / GP i Mathematica są świetnymi językami programowania.
Eelvex 29.01.11

@Eelvex, nie, łamią jedną z zasad golfa: używając wbudowanych specyficznych funkcji wysokiego poziomu .
Nakilon

Nie sądzę, że istnieje taka zasada . Nadal pozostaje kwestią otwartą, kiedy używać funkcji wysokiego poziomu. Zobacz na przykład to meta pytanie
Eelvex

1
28 znaków Range[a,b]~Select~PrimeQ//Tr.
chyanog

6

C (117 w tym NL)

main(a,b,s,j){
s=0,scanf("%d%d",&a,&b);
for(a+=a==1;a<=b;a++)
for(s+=a,j=2;j<a;)
s-=a%j++?0:(j=a);
printf("%d",s);
}

5

C # (294 znaków):

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;}}

Można zrobić wszystkie ints longi zaoszczędzić kilka znaków: long a=...,b=...,t=0,i=a;for(;i<=b;i++). Daje to 288 znaków. Możesz także pozwolić pna długi powrót i po prostu wróć albo 0albo ni skróć pętlę do t+=p(i). Zatem 277 znaków.
Joey,

5

PARI / GP (44 znaki)

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

6
Czy wyborcy nie powinni podawać powodu dla swojego -1?
Eelvex

Opinia negatywna była prawdopodobnie za używanie wbudowanych.
mbomb007

4

BASH Shell

47 znaków

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

Edycja: Właśnie zdałem sobie sprawę, że suma przepełnia się i jest wymuszona podwójnie.

52 50 znaków

Oto nieco dłuższe rozwiązanie, ale radzi sobie również z przepełnieniami

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

tr jest krótszy niż wklej i można usunąć pojedyncze cudzysłowy (klawisz Escape $).
Nabb

@Nabb, naprawię to, gdy tylko dostanę pudełko * nix, lub możesz zrobić honory.
st0le

@Nabb, nie mogę go uruchomić, trdodaje końcowe „+” na końcu, naprawienie zajmie więcej znaków.
st0le,

Ach, przegapiłem to. Chociaż myślę, że nadal możesz zmienić na, awk NF==2{print\$2}aby zapisać bajt na dłuższym rozwiązaniu (nie przypadkowo natrafimy na rozwinięcie nawiasu, ponieważ nie ma przecinków ani ..s).
Nabb

@Nabb, masz rację. Gotowe :)
st0le

4

C #, 183 znaków

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);}}

Byłoby to znacznie krótsze, gdyby nie musiał sprawdzać 1, lub gdyby istniał lepszy sposób na ... W bardziej czytelnym formacie:

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); 
    }
}

Podoba mi się, jak krótki jest to czas, ale zastanawiam się, jak mało wydajny byłby przy obliczaniu do 10 ^ 8!
Nellius 28.01.11

To prawda, ale wydajność nie była zgodna z zasadami!
Nick Larsen

Wiesz, że kompilator ma domyślne wartości numeryczne 0, prawda? To pozwoli ci zaoszczędzić jeszcze kilka znaków
jcolebrand

Daje błąd po skompilowaniu bez niego
Nick Larsen

... ponieważ nigdy nie jest przypisany, zanim zostanie użyty (przez s -= i;ponieważ to po prostu cukier syntaktyczny dla s = s - i;którego próbuje uzyskać dostęp sprzed ustawieniem go)
Nick Larsen

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


To jest golf golfowy! Dlaczego używasz tak długich nazw dla swoich rzeczy?
FUZxxl,

4
Trudno jest znaleźć krótsze nazwy niż c, u, s ... Reszta to biblioteka językowa.
JB

3

Ruby 1.9, 63 znaki

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

Użyj w ten sposób

p[1,100] #=> 1060

Korzystanie z Primeklasy jest jak oszustwo, ale ponieważ rozwiązania Mathematica wykorzystywały wbudowane funkcje główne ...


3

Perl, 62 znaki

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

Ten używa wyrażenia regularnego.


3

Normalne zadanie (Python 3): 95 znaków

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)))

Dodatkowe zadanie (Python 3): 119 znaków

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 znaki)

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

Podobnie jak w przypadku innych rozwiązań, to nie ściśle spełniać wymagania, jak ai bnie są odczytywane ze standardowego wejścia lub z wiersza poleceń. Myślałem jednak, że to dobra alternatywa dla innych rozwiązań Pari / GP i Mathematica.


1
+1: Tak właśnie bym to zrobił, nawet bez gry w golfa.
Charles

2

Common Lisp: (107 znaków)

(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))

działa tylko dla punktów początkowych> = 1


2

APL (25 znaków)

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

Jest to modyfikacja dobrze znanego idiomu ( wyjaśnienie na tej stronie ) do generowania listy liczb pierwszych w APL.

Przykład:

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

2

Współczynnik -> 98

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

Wydajność:

( scratchpad ) 100 1000 s

--- Data stack:
75067

2

R, 57 znaków

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

Czy podanie jest n=2konieczne scan()? Jeśli dane wejściowe są standardowe, czy istnieje problem z pominięciem argumentu i przyjęciem dodatkowego <enter> jest wymagane?
Gaffi

1
Nie, właściwie masz rację, bez której bym sobie poradził. To było wyłącznie ze względów estetycznych (ponieważ wiedziałem, że mój kod i tak nie jest najkrótszy :))
plannapus

Cóż, +1 ode mnie tak samo, ponieważ zdecydowanie nie jest najdłuższy.
Gaffi


1

Perl, 103 znaki

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

Przyjmie wiele linii oddzielonych spacjami i poda odpowiedź dla każdego: D


1

W pytaniu (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}

Przykładowe użycie:

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

Predefiniowane ai b:

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

W funkcji (także 27):

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

1

R (85 znaków)

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

Niezwykle nieefektywny! Jestem prawie pewien, że zajmuje to czas O (n ^ 2). Może to dawać ostrzeżenia o zmuszaniu do podwojenia logiki.

Odbarwione:

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 znaki):

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(i odpowiednio 0dla False) 3. if i%j==0and i!=j:r=04. if r:p+=[i]5. print(sum(p))(zastępuje ostatnie 4 wiersze)
patrz

Możesz użyć, input()aby być krótszym. Czy możesz if i%j<1andzamiast tego użyć ?
mbomb007


1

05AB1E , 5 bajtów

ŸDp*O

Wypróbuj online!

Ÿ      Push the list [a, ..., b]
 D     Push a duplicate of that list
  p    Replace primes with 1 and everything else with 0
   *   Element-wise multiply the two lists [1*0, 2*1, 3*1, 4*0, ...]
    O  Sum of the final list of primes

0

Python: 110 znaków

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)))

To nie jest wliczone.
jamylak

0

Python, 133

Trochę czarów:

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 (Cóż, nie mam jeszcze wystarczającej liczby powtórzeń, aby zagłosować) Jest to nieprawidłowe w Pythonie 2 lub 3, nie można oczekiwać, że dane wejściowe będą dla ciebie zawierać znaki cudzysłowu. Zmień na raw_input lub użyj python 3 plz
jamylak 30.07. O

Możesz usunąć y+=1i zamiast tego użyć range(y+1)i, ([0]*-~y)[::i]aby zapisać bajt (usunięcie nowej linii). A użycie Python 3 pozwoli ci używać input(), o ile wstawisz po nim nawiasy print, usuwając w ten sposób 4 bajty, ale dodając 1. Warto.
mbomb007

0

133 znaki, Lua (brak wbudowanej funkcji 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)

Oto przykład, w którym dodałem wiersz „print (i)”, aby wyświetlić wszystkie znalezione liczby pierwsze i ich sumę na końcu: http://codepad.org/afUvYHnm .


„A i b można pobrać z wiersza polecenia lub standardowego”. Który z tych dwóch sposobów można przekazać liczby do kodu?
manatwork

1
Zgodnie z tym 13 (cokolwiek ponad nim) nie jest liczbą pierwszą.
st0le

@ st0le Zgodnie z logiką 13 jest „liczbą pierwszą” (ale np. 2 nie jest) - z drugiej strony 13 * 13 = 169 jest znowu „liczbą pierwszą” ...
Howard

0

PowerShell - 94

$a,$b=$args[0,1]
(.{$p=2..$b
while($p){$p[0];$p=@($p|?{$_%$p[0]})}}|
?{$_-gt$a}|
measure -s).sum

0

F # (141)

Jedna trzecia kodu służy do analizowania danych wejściowych.

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"
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.