Somme des nombres premiers entre une plage donnée


27

Écrivez le code le plus court pour trouver la somme des nombres premiers entre aet b(inclus).

Contribution

  1. aet bpeut être pris depuis la ligne de commande ou stdin (espace séparé)
  2. Supposons 1 <= a <= b <=10 8

Sortie Imprimez simplement la somme avec un caractère de nouvelle ligne.

Points bonus

  1. Si le programme accepte plusieurs plages (imprimez une somme sur chaque ligne), vous obtenez des points supplémentaires. :)

La limite supérieure est trop grande pour permettre de nombreuses solutions intéressantes (si elles doivent être achevées dans un délai raisonnable, au moins).
hallvabo

@hallvabo Vous trouvez des solutions inefficaces intéressantes?
Matthieu lu le

@hallvabo, ça va. Je ne pense pas que quiconque se préoccupe d'une solution inefficace. Si un autre objet, je serai plus qu'heureux d'abaisser la limite
st0le

Je viens de créer et d'exécuter une version peu optimisée ou concise du programme en C #, en utilisant 1 à 10 ^ 8. En supposant que mon algorithme est correct, il a fonctionné en moins de 1m30 et n'a pas débordé longtemps. Cela me semble être une fine limite supérieure!
Nellius

Une vérification simple et rapide: somme des nombres premiers entre 1 et 100 = 1060.
Nellius

Réponses:


15

J, 41 32 19 caractères:

Mise à jour

(tamis simple)

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

par exemple

100 g 1
1060
250000x g 48
2623030823

précédent

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

par exemple:

100 f 1
1060

11

Mathematica 7 (31 caractères en texte brut)

Si la solution PARI / GP le permet, alors:

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

À quoi veux-tu en venir? PARI / GP et Mathematica sont des langages de programmation fins.
Eelvex

@Eelvex, non, ils enfreignent l'une des règles du golf: utiliser des fonctions spécifiques de haut niveau intégrées .
Nakilon

Je ne pense pas qu'il y ait un tel règle . Il est toujours difficile de savoir quand utiliser des fonctions de haut niveau. Voir par ex. cette méta-question
Eelvex

1
28 caractères Range[a,b]~Select~PrimeQ//Tr .
chyanog

6

C (117 dont 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 caractères):

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

Vous pouvez faire toutes vos ints longet enregistrer quelques caractères: long a=...,b=...,t=0,i=a;for(;i<=b;i++). Cela porte à 288 caractères. Vous pouvez également laisser prevenir un long et simplement retourner l'un 0ou l' autre net raccourcir la boucle à t+=p(i). 277 caractères, alors.
Joey

5

PARI / GP (44 caractères)

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

6
Les électeurs ne devraient-ils pas donner une raison à leur -1?
Eelvex

Le downvote était probablement dû à l'utilisation de modules intégrés.
mbomb007

4

BASH Shell

47 personnages

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

Edit: Je viens de réaliser que la somme déborde et est contrainte comme un double.

52 50 caractères

Voici une solution un peu plus longue, mais gère également les débordements

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

tr est plus court que coller et vous pouvez supprimer les guillemets simples (échapper à $).
Nabb

@Nabb, le réparera dès que je mettrai la main sur une boîte * nix, ou vous pourriez faire les honneurs.
st0le

@Nabb, ne peut pas le faire fonctionner, trajoute un «+» à la fin, le corriger prendra plus de caractères.
st0le

Ah, ça m'a manqué. Bien que je pense que vous pouvez toujours changer pour awk NF==2{print\$2}enregistrer un octet sur la solution plus longue (nous ne rencontrerons pas accidentellement l'expansion d'accolade car il n'y a pas de virgule ou de ..s).
Nabb

@Nabb, vous avez raison. Fait :)
st0le

4

C #, 183 caractères

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

Ce serait beaucoup plus court s'il ne fallait pas vérifier 1, ou s'il y avait une meilleure façon de ... Dans un format plus lisible:

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

J'aime sa brièveté, mais je me demande à quel point ce serait inefficace pour calculer jusqu'à 10 ^ 8!
Nellius

C'est vrai, mais l'efficacité n'était pas dans les règles!
Nick Larsen

Vous savez que le compilateur met par défaut les chiffres à 0, n'est-ce pas? Cela vous éviterait quelques autres caractères
jcolebrand

Donne une erreur lorsqu'il est compilé sans lui
Nick Larsen

... car il n'est jamais attribué avant d'être utilisé (via s -= i;car c'est juste du sucre syntaxique pour s = s - i;lequel il essaie d'accéder savant de le configurer)
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


C'est du code-golf! Pourquoi utilisez-vous des noms aussi longs pour vos affaires?
FUZxxl

4
Il est difficile de trouver des noms plus courts que c, u, s ... Le reste est une bibliothèque standard de langue.
JB

3

Ruby 1.9, 63 caractères

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

Utilisez comme ça

p[1,100] #=> 1060

Utiliser la Primeclasse ressemble à de la triche, mais comme les solutions Mathematica utilisaient des fonctions principales intégrées ...


3

Perl, 62 caractères

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

Celui-ci utilise l'expression rationnelle du nombre premier.


3

Tâche normale (Python 3): 95 caractères

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

Tâche bonus (Python 3): 119 caractères

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 caractères)

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

Comme certaines autres solutions, cela ne répond pas strictement aux exigences, aet bn'est pas lu depuis stdin ou la ligne de commande. Je pensais cependant que c'était une bonne alternative aux autres solutions Pari / GP et Mathematica.


1
+1: C'est comme ça que je le ferais, même sans jouer au golf.
Charles

2

Lisp commun: (107 caractères)

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

ne fonctionne que pour les points de départ> = 1


2

APL (25 caractères)

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

Ceci est une modification d'un idiome bien connu (voir cette page pour une explication) pour générer une liste de nombres premiers en APL.

Exemple:

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

2

Facteur -> 98

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

Sortie:

( scratchpad ) 100 1000 s

--- Data stack:
75067

2

R, 57 caractères

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

La spécification est-elle n=2nécessaire dans scan()? Si l'entrée est standard, y a-t-il un problème à omettre l'argument et à supposer qu'un <enter> supplémentaire est requis?
Gaffi

1
Non, en fait tu as raison, j'aurais pu m'en passer. C'était purement pour des raisons esthétiques (puisque je savais que mon code n'était pas le plus court de toute façon :))
plannapus

Eh bien, +1 de moi tout de même, car ce n'est certainement pas le plus long.
Gaffi


1

Perl, 103 caractères

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

Il acceptera plusieurs lignes séparées par des espaces et donnera la réponse pour chacune: D


1

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

Exemple d'utilisation:

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

Prédéfini aet b:

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

En fonction (également 27):

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

1

R (85 caractères)

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

Extrêmement inefficace! Je suis sûr que cela prend du temps O (n ^ 2). Il pourrait donner des avertissements sur la contrainte d'un double à une logique.

Désobfusqué:

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 caractères):

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(et respectivement 0pour False) 3. if i%j==0and i!=j:r=04. if r:p+=[i]5. print(sum(p))(remplace les 4 dernières lignes)
voir

Vous pouvez utiliser input()pour être plus court. Aussi, pouvez-vous utiliser à la if i%j<1andplace?
mbomb007


1

05AB1E , 5 octets

ŸDp*O

Essayez-le en ligne!

Ÿ      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 chars

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

This is not inclusive.
jamylak

0

Python, 133

A little bit of sorcery:

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 (Well I don't have enough rep to downvote yet) This is invalid in Python 2 or 3, you can't expect input to conveniently contain quotation marks for you. Change to raw_input or use python 3 plz
jamylak

You can remove y+=1 and instead use range(y+1) and ([0]*-~y)[::i] to save a byte (removing the newline). And using Python 3 will allow you to use input(), as long as you put parentheses after print, therefore removing 4 bytes, but adding 1. Worth it.
mbomb007

0

133 chars, Lua (no is_prime in-built function)

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)

Here's an example where I added the line "print(i)" to display all primes found and the sum at the end of them: http://codepad.org/afUvYHnm.


“a and b can be taken from command line or stdin” In which of those two ways can the numbers be passed to your code?
manatwork

1
According to this 13 (anything over it) is not a prime number.
st0le

@st0le According to the logic 13 is a "prime" (but e.g. 2 is not) - on the other hand 13*13 = 169 is "prime" again...
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)

One third of the code is for parsing the 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"
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.