Somma dei numeri primi tra un determinato intervallo


27

Scrivi il codice più breve per trovare la somma dei numeri primi tra ae b(compreso).

Ingresso

  1. ae bpuò essere preso dalla riga di comando o stdin (spazio separato)
  2. Assumi 1 <= a <= b <=10 8

Output Basta stampare la somma con un carattere di nuova riga.

Punti bonus

  1. Se il programma accetta più intervalli (stampa una somma su ogni riga), otterrai punti extra. :)

Il limite superiore è troppo grande per consentire molte soluzioni interessanti (se almeno devono essere completate in tempi ragionevoli).
hallvabo,

@hallvabo Trovi interessanti le soluzioni inefficienti?
Matteo Leggi il

@hallvabo, va bene. Non penso che a nessuno interessi una soluzione inefficiente. Se l'oggetto di altri, sarò più che felice di abbassare il limite
st0le

Ho appena creato ed eseguito una versione non molto ottimizzata o concisa del programma in C #, usando da 1 a 10 ^ 8. Supponendo che il mio algoritmo sia corretto, ha funzionato in meno di 1m30s e non ha traboccato da molto tempo. Mi sembra un bel limite superiore per me!
Nellius,

Un rapido controllo facile: somma di numeri primi tra 1 e 100 = 1060.
Nellius

Risposte:


15

J, 41 32 19 caratteri:

Aggiornare

(setaccio semplice)

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

per esempio

100 g 1
1060
250000x g 48
2623030823

Precedente

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

per esempio:

100 f 1
1060

11

Mathematica 7 (31 caratteri in testo semplice)

Se la soluzione PARI / GP è consentita, allora:

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

Qual è il tuo punto? PARI / GP e Mathematica sono ottimi linguaggi di programmazione.
Eelvex,

@Eelvex, no, infrangono una delle regole del golf: utilizzando funzioni di alto livello specifiche integrate .
Nakilon,

Non credo ci sia una tale regola . È ancora una questione aperta quando utilizzare le funzioni di alto livello. Vedi per es. questa meta domanda
Eelvex,

1
28 caratteri Range[a,b]~Select~PrimeQ//Tr.
chyanog,

6

C (117 incluso 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 caratteri):

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

È possibile effettuare tutti i vostri ints longe salvare un paio di caratteri: long a=...,b=...,t=0,i=a;for(;i<=b;i++). Questo arriva a 288 caratteri. Puoi anche lasciare pun valore lungo e solo tornare indietro 0o naccorciare il ciclo t+=p(i). 277 caratteri, quindi.
Joey,

5

PARI / GP (44 caratteri)

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

6
Gli elettori in calo non dovrebbero dare una ragione per il loro -1?
Eelvex,

Il downvote era probabilmente per l'utilizzo di built-in.
mbomb007,

4

Shell BASH

47 personaggi

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

Modifica: appena realizzato la somma trabocca e viene forzato come doppio.

52 50 personaggi

Ecco una soluzione un po 'più lunga, ma gestisce anche gli overflow

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

tr è più corto di incolla ed è possibile rimuovere le virgolette singole (sfuggire a $).
Nabb,

@Nabb, lo risolverò non appena avrò le mani su una * nix box, o potresti fare gli onori.
via

@Nabb, non riesco a farlo funzionare, traggiunge un '+' finale alla fine, risolvendolo richiederà più caratteri.
via

Ah, l'ho perso. Anche se penso che puoi ancora passare a awk NF==2{print\$2}per salvare un byte sulla soluzione più lunga (non ci imbatteremo accidentalmente nell'espansione del controvento perché non ci sono virgole o virgole ..).
Nabb,

@Nabb, hai ragione. Fatto :)
st0le,

4

C #, 183 caratteri

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

Questo sarebbe molto più breve se non fosse necessario controllare per 1 o se ci fosse un modo migliore per ... In un formato più leggibile:

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

Mi piace quanto sia breve, ma mi chiedo quanto sarebbe inefficiente quando si calcolano fino a 10 ^ 8!
Nellius,

Vero, ma l'efficienza non era nelle regole!
Nick Larsen,

Sai che il compilatore imposta automaticamente i valori numerici su 0, giusto? Ciò ti risparmierebbe un altro paio di
personaggi

Dà errore se compilato senza di essa
Nick Larsen,

... perché non è mai stato assegnato prima di essere utilizzato (tramite s -= i;perché è solo lo zucchero sintattico per il s = s - i;quale tenta di accedere sprima di impostarlo)
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


Questo è code-golf! Perché usi nomi così lunghi per le tue cose?
FUZxxl,

4
È difficile trovare nomi più brevi di c, u, s ... Il resto è una libreria standard di lingua.
JB

3

Ruby 1.9, 63 caratteri

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

Usa così

p[1,100] #=> 1060

Usare la Primeclasse è come imbrogliare, ma dal momento che le soluzioni Mathematica hanno utilizzato funzioni prime integrate ...


3

Perl, 62 caratteri

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

Questo usa il numero primo regex.


3

Attività normale (Python 3): 95 caratteri

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

Attività bonus (Python 3): 119 caratteri

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

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

Come altre soluzioni, questo non strettamente soddisfa i requisiti, come ae bnon vengono letti dallo standard input o riga di comando. Ho pensato che fosse comunque una bella alternativa alle altre soluzioni Pari / GP e Mathematica.


1
+1: Questo è il modo in cui lo farei, anche senza giocare a golf.
Charles,

2

Lisp comune: (107 caratteri)

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

Funziona solo per i punti di partenza> = 1


2

APL (25 caratteri)

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

Questa è una modifica di un linguaggio ben noto (vedi questa pagina per una spiegazione) per generare un elenco di numeri primi in APL.

Esempio:

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

2

Fattore -> 98

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

Produzione:

( scratchpad ) 100 1000 s

--- Data stack:
75067

2

R, 57 caratteri

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

È n=2necessario specificare in scan()? Se l'input è standard, c'è un problema con l'omissione dell'argomento e supponendo che sia richiesto un <enter> extra?
Gaffi,

1
No, in realtà hai ragione, avrei potuto fare a meno. È stato puramente per motivi estetici (poiché sapevo che il mio codice non era il più breve comunque :))
plannapus,

Bene, +1 da parte mia lo stesso, dato che sicuramente non è il più lungo.
Gaffi,


1

Perl, 103 caratteri

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

Accetterà più righe separate da spazio e darà la risposta per ciascuna: D


1

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

Esempio di utilizzo:

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

matematica , 27

Predefinito ae b:

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

Come funzione (anche 27):

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

1

R (85 caratteri)

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

Estremamente inefficiente! Sono abbastanza sicuro che ci vorrà O (n ^ 2) tempo. Potrebbe dare avvertimenti sul forzare un doppio in un logico.

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

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(e rispettivamente 0per False) 3. if i%j==0and i!=j:r=04. if r:p+=[i]5. print(sum(p))(sostituisce le ultime 4 righe)
vedi

Puoi usare input()per essere più corto. Inoltre, puoi usare if i%j<1andinvece?
mbomb007,

1

GolfScript, 27 24 byte

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

Questo si basa sull'algoritmo del numero primo di @w0lf .


1

05AB1E , 5 byte

ŸDp*O

Provalo 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 caratteri

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

Questo non è inclusivo.
jamylak,

0

Python, 133

Un po 'di stregoneria:

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 (Beh, non ho ancora abbastanza rappresentante per il downvote) Questo non è valido in Python 2 o 3, non puoi aspettarti che l'input contenga opportunamente virgolette per te. Passa a raw_input o usa python 3 plz
jamylak il

È possibile rimuovere y+=1e invece utilizzare range(y+1)e ([0]*-~y)[::i]per salvare un byte (rimuovendo la nuova riga). E l'uso di Python 3 ti permetterà di usare input(), purché tu metta le parentesi dopo print, quindi rimuovendo 4 byte, ma aggiungendo 1. Ne vale la pena.
mbomb007,

0

133 caratteri, Lua (nessuna funzione incorporata 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)

Ecco un esempio in cui ho aggiunto la riga "print (i)" per visualizzare tutti i numeri primi trovati e la somma alla fine di essi: http://codepad.org/afUvYHnm .


"Aeb possono essere presi dalla riga di comando o stdin" In quale di questi due modi i numeri possono essere passati al tuo codice?
arte

1
Secondo questo 13 (qualsiasi cosa su di esso) non è un numero primo.
st0le

@ st0le Secondo la logica 13 è un "primo" (ma ad esempio 2 non lo è) - d'altra parte 13 * 13 = 169 è di nuovo "primo" ...
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)

Un terzo del codice serve per analizzare l'input.

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"
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.