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. :)
st0le
źródło
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
Eelvex
źródło
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]
Nakilon
źródło
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);
}
Alexandru
źródło
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;}}
Nellius
źródło
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))
Eelvex
źródło
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
st0le
źródło
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); 
    }
}
Nick Larsen
źródło
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

Ming-Tang
źródło
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 ...

Michael Kohl
źródło
3

Perl, 62 znaki

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

Ten używa wyrażenia regularnego.

ninjalj
źródło
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)))
jamylak
źródło
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.

DanaJ
źródło
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

tobyodavies
źródło
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
Dillon Cower
źródło
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
defhlt
źródło
2

R, 57 znaków

a=scan();b=a[1]:a[2];sum(b[rowSums(!outer(b,b,`%%`))==2])
plannapus
źródło
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
2

Japt , 7 bajtów

òV fj x

Wypróbuj tutaj.

Erik the Outgolfer
źródło
Witamy w Japt :)
Shaggy,
@Shaggy Początkowo próbowałem znaleźć „główny zakres” wbudowany w Japt, ale potem zdecydowałem się przyjąć wyzwanie: p
Erik Outgolfer
Biorąc pod uwagę liczbę wyzwań związanych z liczbami pierwszymi, skrót do fj<space>może być przydatny.
Kudłaty,
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

anonimowy tchórz
źródło
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
sinedcm
źródło
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;}}}
Saumil
źródło
1

Mathematica , 27

Predefiniowane ai b:

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

W funkcji (także 27):

Tr[Range@##~Select~PrimeQ]&
Mr.Wizard
źródło
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)
raptortech97
źródło
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))
Jan
źródło
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
Galoubet
źródło
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)))
zxul767
źródło
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)
JBernardo
źródło
-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 .

użytkownik8524
źródło
„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
Rynant
źródło
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"
Ming-Tang
źródło