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.