Сумма простых чисел между заданным диапазоном


27

Напишите кратчайший код для нахождения суммы простых чисел между aи b(включительно).

вход

  1. aи bможет быть взят из командной строки или стандартного ввода (разделенных пробелами)
  2. Предположим, 1 <= a <= b <=10 8

Выходные данные Просто напечатайте сумму с символом новой строки.

Бонусные очки

  1. Если программа принимает несколько диапазонов (выведите одну сумму в каждой строке), вы получите дополнительные баллы. :)

Верхний предел слишком велик, чтобы можно было принять много интересных решений (по крайней мере, если они должны быть выполнены в разумные сроки).
hallvabo

@hallvabo Вам интересны неэффективные решения?
Мэтью Читал

@hallvabo, все в порядке. Я не думаю, что кто-то возражает против неэффективного решения. Если у кого-то другой объект, я буду более чем счастлив снизить предел
st0le

Только что сделал и запустил не очень оптимизированную или сжатую версию программы на C #, используя от 1 до 10 ^ 8. Предполагая, что мой алгоритм верен, он работал менее чем за 1 мсек и долго не переполнялся. Похоже, хороший верхний предел для меня!
Неллиус

Быстрая простая проверка: сумма простых чисел от 1 до 100 = 1060.
Неллиус

Ответы:


15

J, 41 32 19 символов:

Обновить

(простое сито)

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

например

100 g 1
1060
250000x g 48
2623030823

предыдущий

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

например:

100 f 1
1060

11

Mathematica 7 (31 символ в простом тексте)

Если разрешено решение PARI / GP, то:

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

В чем ваша точка зрения? PARI / GP и Mathematica - прекрасные языки программирования.
Eelvex

@Eelvex, нет, они нарушают одно из правил игры в гольф: использование встроенных специальных функций высокого уровня .
Накилон

Я не думаю, что есть такое правило . Вопрос о том, когда использовать функции высокого уровня, остается открытым. Смотрите, например. этот мета вопрос
Eelvex

1
28 символов Range[a,b]~Select~PrimeQ//Tr.
13

6

C (117, включая 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 символа):

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

Вы можете сделать все intS longи сохранить несколько символов: long a=...,b=...,t=0,i=a;for(;i<=b;i++). Это получает до 288 символов. Вы также можете позволить pвозвращать long и просто возвращать либо, 0либо nсокращать цикл до t+=p(i). 277 символов, тогда.
Джои

5

PARI / GP (44 символа)

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

6
Разве избиратели не должны давать повод для их -1?
Eelvex

Вероятно, понижение было за использование встроенных модулей.
mbomb007

4

BASH Shell

47 персонажей

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

Редактировать: только что понял, что сумма переполняется и приводится в двойном размере.

52 50 персонажей

Вот немного более длинное решение, но также справляется с переполнением

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

tr короче, чем вставить, и вы можете удалить одинарные кавычки (экранировать $).
Набб

@Nabb, исправлю это, как только я получу * nix коробку, или ты сможешь сделать почести.
st0le

@Nabb, не могу заставить его работать, trдобавляет в конце завершающий символ '+', исправление которого займет больше символов.
st0le

Ах, пропустил это. Хотя я думаю, что вы все равно можете перейти на awk NF==2{print\$2}сохранение байта в более длинном решении (мы не будем случайно сталкиваться с расширением скобки, потому что нет запятых или ..s).
Набб

@ Набб, ты прав. Готово :)
st0le

4

C #, 183 символа

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

Это было бы намного короче, если бы не нужно было проверять 1 или был бы лучший способ ... В более читаемом формате:

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

Мне нравится, насколько это коротко, но мне интересно, насколько неэффективно это будет при расчете до 10 ^ 8!
Неллиус

Правда, эффективности не было в правилах!
Ник Ларсен

Вы знаете, компилятор по умолчанию для чисел 0, верно? Это спасет вас еще пару символов
jcolebrand

Выдает ошибку при компиляции без него
Ник Ларсен

... потому что он никогда не назначается до того, как его использовать (через, s -= i;потому что это просто синтаксический сахар, к s = s - i;которому пытается обратиться sперед его настройкой)
Ник Ларсен,

3

Хаскелл (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


Это код-гольф! Почему вы используете такие длинные имена для своих вещей?
FUZxxl

4
Трудно найти более короткие имена, чем c, u, s ... Остальное - языковая стандартная библиотека.
JB

3

Ruby 1,9, 63 символа

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

Используйте как это

p[1,100] #=> 1060

Использование Primeкласса кажется обманом, но поскольку в решениях Mathematica используются встроенные простые функции ...


3

Perl, 62 символа

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

Этот использует регулярное выражение простого числа.


3

Обычное задание (Python 3): 95 символов

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

Бонусное задание (Python 3): 119 символов

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

Пари / ГП (24 символа)

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

Как и некоторые другие решения, это не совсем соответствует требованиям, так как aи bне читается из стандартного ввода или командной строки. Однако я подумал, что это хорошая альтернатива другим решениям Pari / GP и Mathematica.


1
+1: Я бы так и сделал, даже без игры в гольф.
Чарльз

2

Common Lisp: (107 символов)

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

работает только для начальных точек> = 1


2

APL (25 символов)

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

Это модификация хорошо известной идиомы (см. Эту страницу для объяснения) для генерации списка простых чисел в APL.

Пример:

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

2

Фактор -> 98

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

Выход:

( scratchpad ) 100 1000 s

--- Data stack:
75067

2

R, 57 символов

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

n=2Нужно ли указывать в scan()? Если вход является стандартным, есть ли проблема с пропуском аргумента и предположением, что требуется дополнительный <enter>?
Гаффи

1
Нет, на самом деле ты прав, без чего я мог бы обойтись. Это было чисто по эстетическим соображениям (так как я знал, что мой код в любом случае не самый короткий :))
plannapus

Ну, +1 от меня точно такой же, так как он точно не самый длинный.
Гаффи

2

Добро пожаловать в Japt :)
Shaggy

@ Shaggy Изначально я пытался найти встроенный в Japt «простой диапазон», но затем решил принять вызов: p
Эрик Outgolfer

Учитывая, сколько задач связано с простыми числами, ярлык для fj<space>может быть полезен.
Лохматый

1

Perl, 103 символа

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

Он примет несколько разделенных пробелом строк и даст ответ для каждой: D


1

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

Пример использования:

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

Математика , 27

Предопределено aи b:

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

Как функция (также 27):

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

1

R (85 символов)

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

Крайне неэффективно! Я почти уверен, что это займет O (n ^ 2) времени. Это может дать предупреждение о принуждении двойного к логическому.

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 символа):

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(и соответственно 0для False) 3. if i%j==0and i!=j:r=04. if r:p+=[i]5. print(sum(p))(заменяет последние 4 строки)
seequ

Вы можете использовать, input()чтобы быть короче. Кроме того, вы можете использовать if i%j<1andвместо этого?
mbomb007



0

Питон: 110 символов

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

Это не включено.
jamylak

0

Питон, 133

Немного колдовства:

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 (Ну, у меня пока недостаточно повторений для понижения голосов) Это недопустимо в Python 2 или 3, вы не можете ожидать, что ввод будет содержать удобные для вас кавычки. Измените на raw_input или используйте python 3 plz
jamylak

Вы можете удалить y+=1и вместо этого использовать range(y+1)и ([0]*-~y)[::i]для сохранения байта (удаление новой строки). А использование Python 3 позволит вам использовать input()до тех пор, пока вы ставите круглые скобки после print, поэтому удаляете 4 байта, но добавляете 1. Стоит того.
mbomb007

0

133 символа, Lua (нет встроенной функции 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)

Вот пример, где я добавил строку «print (i)» для отображения всех найденных простых чисел и суммы в конце: http://codepad.org/afUvYHnm .


«A и b можно взять из командной строки или стандартного ввода». Каким из этих двух способов можно передать числа в ваш код?
Манатворк

1
Согласно этому 13 (что-нибудь по этому) не простое число.
st0le

@ st0le Согласно логике 13 - это "простое число" (но, например, 2 нет) - с другой стороны, 13 * 13 = 169 снова "простое" ...
Говард

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)

Одна треть кода предназначена для анализа ввода.

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"
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.