Сума простих розмірів між заданим діапазоном


27

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

Вхідні дані

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

Вихід Просто надрукуйте суму новим рядком.

Бонусні бали

  1. Якщо програма приймає декілька діапазонів (друкуйте по одній сумі в кожному рядку), ви отримуєте додаткові бали. :)

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

@hallvabo Ви вважаєте цікавими неефективні рішення?
Матвій

@hallvabo, це нормально. Я не думаю, що хтось проти розумного рішення. Якщо інший об’єкт, я буду більш ніж радий знизити межу
st0le

Щойно зробив і запустив не дуже оптимізовану або стисну версію програми в C #, використовуючи від 1 до 10 ^ 8. Якщо припустити, що алгоритм мій правильний, він пробіг менше ніж 1 м30, і не переповнювався довго. Мені здається, тонка верхня межа для мене!
Нелліус

Швидкий простий перевірки: сума простих
розмірів

Відповіді:


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

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

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повернути довгий і просто повернути або 0або nскоротити цикл до t+=p(i). 277 символів, значить.
Joey

5

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

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

6
Чи не повинні виборці вказувати причину свого -1?
Ельвакс

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

4

БАШ Шелл

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

@Nabb, виправлю це, як тільки я дістану руки до * nix коробки, або ви можете зробити відзнаку.
st0le

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

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

@Nabb, ти маєш рацію. Готово :)
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, чи не так? Це врятує тебе ще пару
годин

Припускає помилку при складанні без неї
Нік Ларсен

... тому що він ніколи не призначається перед його вживанням (через те, 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

Рубін 1,9, 63 символи

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

Використовуйте так

p[1,100] #=> 1060

Використовувати Primeклас відчуває себе обманом, але оскільки рішення Mathematica використовували вбудовані основні функції ...


3

Перл, 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

Pari / GP (24 символи)

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

Як і деякі інші рішення, це не строго відповідати вимогам, так як aі bНЕ зчитується зі стандартного вводу або з командного рядка. Я подумав, що це приємна альтернатива іншим рішенням Pari / GP та Mathematica.


1
+1: Це так, як я б це зробив, навіть без гольфу.
Чарльз

2

Звичайний Лісп (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 від мене так само, як це точно не найдовше.
Gaffi

2

Japt , 7 байт

òV fj x

Спробуйте тут.


Ласкаво просимо в Japt :)
Shaggy

@Shaggy Спочатку я намагався знайти "першу дальність", побудовану в Джапті, але потім вирішив прийняти виклик: p
Erik the Outgolfer

З огляду на те, як багато проблем пов'язано з праймерами, ярлик для цього fj<space>може бути корисним.
Shaggy

1

Перл, 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

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). Це може попередити про примушування подвійного до логічного.

Деобфузований:

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 можна взяти з командного рядка або stdin". Яким із цих двох способів можна передати номери у ваш код?
манатура

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.