Soma de números primos entre determinado intervalo


27

Escreva o código mais curto para encontrar a soma dos números primos entre ae b(inclusive).

Entrada

  1. ae bpode ser obtido da linha de comando ou stdin (espaço separado)
  2. Suponha que 1 <= a <= b <=10 8

Saída Basta imprimir a soma com um caractere de nova linha.

Pontos bônus

  1. Se o programa aceitar vários intervalos (imprimir uma soma em cada linha), você ganha pontos extras. :)

O limite superior é muito grande para permitir muitas soluções interessantes (se elas tiverem que ser concluídas em tempo razoável, pelo menos).
hallvabo

@hallvabo Você acha soluções ineficientes interessantes?
Mateus Leia

@hallvabo, tudo bem. Eu não acho que alguém se importe com uma solução ineficiente. Se o objeto de outra pessoa, terei o maior prazer em diminuir o limite
st0le

Acabei de criar e executar uma versão não muito otimizada ou concisa do programa em C #, usando 1 a 10 ^ 8. Supondo que meu algoritmo esteja correto, ele rodava abaixo de 1m30s e não transbordou por muito tempo. Parece um bom limite superior para mim!
Nellius

Uma rápida fácil verificação: soma dos números primos entre 1 e 100 = 1060.
Nellius

Respostas:


15

J, 41 32 19 caracteres:

Atualizar

(peneira simples)

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

por exemplo

100 g 1
1060
250000x g 48
2623030823

Anterior

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

por exemplo:

100 f 1
1060

11

Mathematica 7 (31 caracteres em texto sem formatação)

Se a solução PARI / GP for permitida, então:

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

Onde você quer chegar? PARI / GP e Mathematica são excelentes linguagens de programação.
Eelvex 29/01

@Eelvex, não, eles violam uma das regras de golfe: usando funções específicas de alto nível .
Nakilon

Eu não acho que exista essa regra . Ainda é um assunto em aberto quando usar funções de alto nível. Veja para ex. esta meta questão
Eelvex 29/01

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

6

C (117 incluindo 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 caracteres):

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

Você pode fazer todos os seus ints longe salvar alguns caracteres: long a=...,b=...,t=0,i=a;for(;i<=b;i++). Isso leva a 288 caracteres. Você também pode deixar pretornar um longo e simplesmente retornar um 0ou ne diminuir o loop para t+=p(i). 277 caracteres, então.
Joey

5

PARI / GP (44 caracteres)

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

6
Os eleitores não devem dar uma razão para o seu -1?
Eelvex

O voto negativo foi provavelmente por usar built-ins.
mbomb007

4

BASH Shell

47 Personagens

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

Edit: Apenas percebi que a soma transborda e é coagida como um duplo.

52 50 caracteres

Aqui está uma solução um pouco mais longa, mas também lida com estouros

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

tr é mais curto que colar e você pode remover as aspas simples (escapar da $).
Nabb

@ Nabb, irá corrigi-lo assim que eu colocar minhas mãos em uma caixa * nix, ou você poderá fazer as honras.
st0le

O @Nabb, não pode fazê-lo funcionar, tradiciona um '+' à direita no final, corrigindo-o levará mais caracteres.
st0le 6/02/11

Ah, senti falta disso. Embora eu ache que você ainda pode mudar para awk NF==2{print\$2}salvar um byte na solução mais longa (não acidentalmente encontraremos expansão de chaves porque não há vírgulas ou ..s).
Nabb 06/02

@ Nabb, você está certo. Feito :)
st0le

4

C #, 183 caracteres

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

Isso seria muito mais curto se não fosse necessário verificar 1 ou se houvesse uma maneira melhor de ... Em um formato mais legível:

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

Eu gosto de como isso é curto, mas me pergunto como seria ineficiente ao calcular até 10 ^ 8!
Nellius

É verdade, mas a eficiência não estava nas regras!
Nick Larsen

Você sabe que o compilador padroniza numéricos para 0, certo? Isso poupará mais alguns caracteres por aí
jcolebrand

Dá erro quando compilado sem ele
Nick Larsen

... porque nunca é atribuído antes de ser utilizado (via s -= i;porque isso é apenas açúcar sintático para s = s - i;que tenta o acesso santes de defini-lo)
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


Isso é código-golfe! Por que você usa nomes tão longos para as suas coisas?
FUZxxl

4
É difícil encontrar nomes mais curtos que c, u, s ... O resto é uma biblioteca de idiomas padrão.
JB

3

Ruby 1.9, 63 caracteres

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

Use assim

p[1,100] #=> 1060

Usar a Primeclasse parece trapaça, mas como as soluções Mathematica usavam funções principais incorporadas ...


3

Perl, 62 caracteres

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

Este usa o número regular regex.


3

Tarefa normal (Python 3): 95 caracteres

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

Tarefa de bônus (Python 3): 119 caracteres

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

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

Like some other solutions, this doesn't strictly meet the requirements, as a and b aren't read from stdin or the command line. I thought it was a nice alternative to the other Pari/GP and Mathematica solutions however.


1
+1: This is the way I'd actually do it, even without golfing.
Charles

2

Common Lisp: (107 chars)

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

only works for starting points >= 1


2

APL (25 characters)

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

This is a modification of a well-known idiom (see this page for an explanation) for generating a list of primes in APL.

Example:

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

2

Factor -> 98

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

Output:

( scratchpad ) 100 1000 s

--- Data stack:
75067

2

R, 57 characters

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

Is specifying n=2 necessary in scan()? If the input is standard, is there a problem with omitting the argument and assuming an extra <enter> is required?
Gaffi

1
No actually you're right I could have done without. It was purely for aesthetic reasons (since i knew my code wasn't the shortest anyway :) )
plannapus

Well, +1 from me just the same, as it's definitely not the longest.
Gaffi


1

Perl, 103 chars

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

It'll accept multiple space separated lines and give the answer for each :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}

Sample Usage:

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

Predefined a and b:

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

As a function (also 27):

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

1

R (85 characters)

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

Extremely inefficient! I'm pretty sure it takes O(n^2) time. It might give warnings about coercing a double to a logical.

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

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 (and respectively 0 for False) 3. if i%j==0and i!=j:r=0 4. if r:p+=[i] 5. print(sum(p)) (replaces last 4 lines)
seequ

You can use input() to be shorter. Also, can you use if i%j<1and instead?
mbomb007


1

05AB1E, 5 bytes

ŸDp*O

Try it 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 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"
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.