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


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.