Функція підрахунку простих чисел


28

Вступ

Функція підрахунку основного складу , також відома як функція Pi , повертає кількість простих чисел, менших або рівних x.π(x)

Виклик

Ваша програма прийме ціле число x, яке ви можете вважати позитивним, і виведе єдине ціле число, яке дорівнює кількості простих чисел, меншим або рівним x. Це завдання з , тому переможцем стане програма з найменшою кількістю байтів.

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

Приклади введення

Вхід:
1
Вихід:
0

Вхід:
2
Вихід:
1

Вхід:
5
Вихід:
3

A000720 - OEIS


3
А як щодо інших функцій, пов’язаних з простими елементами? Наприклад, функціонер "Наступний прайм"
Луїс Мендо

6
як щодо простих функцій факторизації?
Мальтісен

4
Ласкаво просимо до головоломки програмування та коду для гольфу!
Аднан

6
Як сказав Аднан, ласкаво просимо до PPCG! Для майбутніх проблем дозвольте мені порекомендувати Sandbox, де ви можете опублікувати виклик, щоб отримати змістовні відгуки та критику, перш ніж розміщувати його на головному сайті.
AdmBorkBork

Я думаю, що це те, що @TheBikingViking мав на увазі посилання на: Пов'язане
mbomb007

Відповіді:


36

05AB1E , 3 байти

!fg

Це передбачає, що вбудовані факторизації дозволені. Спробуйте в Інтернеті!

Як це працює

!    Compute the factorial of the input.
 f   Determine its unique prime factors.
  g  Get the length of the resulting list.

5
Це справді розумно!
mbomb007

5
Чорт, я отримую rekt моєю рідною мовою для другого разу ха - ха. +1
Аднан

Чому це працює?
Олівер Ні

1
@Oliver Оскільки факторіал n ділиться на всі цілі числа 1, ..., n (зокрема, прості p ≤ n ), і жоден інший простий q> n, оскільки він не може бути виражений як добуток менших чисел.
Денніс

10

Python 2, 45 байт

f=lambda n,k=1,p=1:n/k and p%k+f(n,k+1,p*k*k)

Використовується простий генератор теореми Вілсона . Продукт pвідстежує (k-1)!^2, і p%kце 1 для праймерів і 0 для непрозорих.


Розрахувати фабрику знизу вгору - чудова хитрість. +1
ETHproductions

6

MATL , 11, 10, 8 , 5 байт

:pYFn

Спробуйте в Інтернеті!

Я написав версію, в якій було дуже цікаве пояснення того, як працюють матриці MATL:

:YF!s1=1

Але це вже не актуально. Перевірте історію редагувань, якщо ви хочете її побачити.

Нове пояснення:

:p      % Compute factorial(input)
  YF    % Get the exponenents of prime factorization
    n   % Get the length of the array

Три байти збереглися завдяки геніальному рішенню Денніса


Коротше використовувати функцію "експоненти простий факторизації", тому що вона векторизується:YF!s1=s
Луїс Мендо

@LuisMendo Це зовсім інший підхід, тому сміливо йдіть уперед і розміщуйте його. (Хоча якщо ви цього не хочете, я щасливо хотів би)
DJMcMayhem

Іди вперед. Я відправлю це в Jelly, щоб попрактикуватися :-)
Луїс Мендо

5

Желе , 8 5 байт

3 байти збережено завдяки @Dennis!

RÆESL

Спробуйте в Інтернеті!

Порт відповіді DJMcMayhem MATL (колишня версія), уточнений Деннісом.

R          Range of input argument
 ÆE        List of lists of exponents of prime-factor decomposition
   S       Vectorized sum. This right-pads inner lists with zeros
    L      Length of result

1
Виправлення: порт Луїса Мендо: відповідь MATL DJMcMayhem. : P
DJMcMayhem

2
Вам потрібна лише максимальна довжина результатів ÆE, оскільки кожен показник відповідає різному основного коефіцієнта. RÆESLдосягає саме цього. !ÆELбуло б ще коротше.
Денніс

1
@Dennis Дякую! Я використав першу пропозицію. Другий - занадто інший, і ваш підхід
Луїс Мендо

5

Шаблони MediaWiki з ParserFunctions , 220 + 19 = 239 байт

{{#ifexpr:{{{2}}}+1={{{1}}}|0|{{#ifexpr:{{{3}}}={{{2}}}|{{P|{{{1}}}|{{#expr:{{{2}}}+1}}|2}}|{{#ifexpr:{{{2}}} mod {{{3}}}=0|{{#expr:1+{{P|{{{1}}}|{{#expr:{{{2}}}+1}}|2}}|{{P|{{{1}}}|{{{2}}}|{{#expr:{{{2}}}+1}}}}}}}}}}}}

Щоб зателефонувати до шаблону:

{{{P|{{{n}}}|2|2}}}

Влаштовано в стилі Lisp:

{{#ifexpr:{{{2}}} + 1 = {{{1}}}|0|
    {{#ifexpr:{{{3}}} = {{{2}}} |
        {{P|{{{1}}}|{{#expr:{{{2}}} + 1}}|2}} |
            {{#ifexpr:{{{2}}} mod {{{3}}} = 0 |
                {{#expr:1 + {{P|{{{1}}}|{{#expr:{{{2}}} + 1}}|2}} |
                {{P|{{{1}}}|{{{2}}}|{{#expr:{{{2}}} + 1}}}}}}}}}}}}

Просто базовий тест на первинність від 2 до n . Числа з трьома дужками навколо них є змінними, де {{{1}}}є п , {{{2}}}є число випробовується, {{{3}}}є фактором , щоб перевірити.


5

Perl, 33 байти

Включає +1 для -p

Дайте вхідний номер на STDIN

primecount.pl

#!/usr/bin/perl -p
$_=1x$_;$_=s%(?!(11+)\1+$)%%eg-2

Дає невірний результат для, 0але це нормально, оп вимагає підтримки лише для додатних цілих чисел.


4

Сітківка, 31 байт

Кількість байтів передбачає кодування ISO 8859-1. Перетворити вхід в одинаковий, генерувати діапазон від 1до n, кожен у своєму рядку. Зіставити прими.

.*
$*
\B
¶$`
m`^(?!(..+)\1+$)..

Спробуйте в Інтернеті - введіть значно більше 2800 разів або втрачається пам'ять.

Список літератури:

Генератор діапазону Мартіна

Мартін-шашка



4

Желе , 13 11 10 9 8 7 6 байт

Не використовуючи вбудованих простих функцій
-1 байт завдяки @miles (використовуйте таблицю)
-1 байт завдяки @Dennis (перетворити з унарного для підрахунку дільників)

ḍþḅ1ċ2

TryItOnline
Або подивіться перші 100 термінів серіїn=[1,100], також на TryItOnline

Як?

ḍþḅ1ċ2 - Main link: n
 þ     - table or outer product, n implicitly becomes [1,2,3,...n]
ḍ      - divides
  ḅ1   - Convert from unary: number of numbers in [1,2,3,...,n] that divide x
                             (numbers greater than x do not divide x)
    ċ2 - count 2s: count the numbers in [1,2,3,...,n] with exactly 2 divisors
                   (only primes have 2 divisors: 1 and themselves)

1
Ви можете дістатися до 7 байт %þ`¬Sċ2за допомогою таблиці залишків.
миль

1
ḍþḅ1ċ2зберігає байт.
Денніс

4

JavaScript (ES6), 45 43 байт

f=(n,x=n)=>n>1&&(--x<2)+(n%x?f(n,x):f(n-1))

Модифікація моєї 36 35 -байтної функції первинності (1 байт збережено @Neil, 2 - @Arnauld):

f=(n,x=n)=>n>1&--x<2||n%x&&f(n,x)

(Я не можу розміщувати це ніде, тому що цей номер є простим? Приймає лише повні програми ...)

Фрагмент тесту


Вау ... мені знадобилося деякий час, щоб зрозуміти. Хороша робота!
todeale

На жаль, це не стосується вашої відповіді, але ви, ймовірно, можете піти з одного &посеред своєї функції первинності.
Ніл

3

PowerShell v2 +, 98 байт

param($n)if($j='001'[$n]){}else{for($i=1;$i-lt$n){for(;'1'*++$i-match'^(?!(..+)\1+$)..'){$j++}}}$j

Попередження: для великих входів це повільно .

В основному пошук, що базується на одинарі, чи є це число простим? , поєднане з forпетлею та $j++лічильником. Трохи додаткової логіки на передній панелі для врахування введення крайових випадків 1і 2завдяки тому, як працює огородження в forпетлях.


3

05AB1E , 5 байт

Передбачається, що вбудовані основні фактори факторизації дозволені.

Код:

LÒ1ùg

Пояснення:

L      # Get the range [1, ..., input]
 Ò     # Prime factorize each with duplicates
  1ù   # Keep the elements with length 1
    g  # Get the length of the resulting array

Використовує кодування CP-1252 . Спробуйте в Інтернеті!


ÅPgце те, що було б зараз, правда?
Чарівний восьминога Урна


3

Желе , 6 байт

Ḷ!²%RS

Тут використовується лише основна арифметика та теорема Вілсона. Спробуйте в Інтернеті! або перевірити всі тестові випадки .

Як це працює

Ḷ!²%RS  Main link. Argument: n

Ḷ       Unlength; yield [0, ..., n - 1].
 !      Factorial; yield [0!, ..., (n - 1)!].
  ²     Square; yield [0!², ..., (n - 1)!²].
    R   Range; yield [1, ..., n].
   %    Modulus; yield [0!² % 1, ..., (n - 1)!² % n].
        By a corollary to Wilson's theorem, (k - 1)!² % k yields 1 if k is prime
        and 0 if k is 1 or composite.
     S  Sum; add the resulting Booleans.

3

C # 5,0 78 77

int F(int n){int z=n;if(n<2)return 0;for(;n%--z!=0;);return(2>z?1:0)+F(n-1);}

Безумовно

int F(int n)
{
    var z = n;
    if (n < 2) return 0;
    for (; n % --z != 0;) ;
    return F(n - 1) + (2 > z ? 1 : 0);
}

@tfbninja так, ти прав, але я дав лише функціональну частину, яка не складена власноруч
Аріель Береславський


класно звучить добре!
FantaC


2

Bash + coreutils, 30

seq $1|factor|egrep -c :.\\S+$

Ідеон.


Bash + coreutils + пакет BSD-ігор, 22

primes 1 $[$1+1]|wc -l

Цей короткий відповідь вимагає , щоб у вас є пакет bsdgames встановлений: sudo apt install bsdgames.



2

C #, 157 байт

n=>{int c=0,i=1,j;bool f;for(;i<=n;i++){if(i==1);else if(i<=3)c++;else if(i%2==0|i%3==0);else{j=5;f=1>0;while(j*j<=i)if(i%j++==0)f=1<0;c+=f?1:0;}}return c;};

Повна програма з тестовими кейсами:

using System;

class a
{
    static void Main()
    {
        Func<int, int> s = n =>
            {
                int c = 0, i = 1, j;
                bool f;
                for (; i <= n; i++)
                {
                    if (i == 1) ;
                    else if (i <= 3) c++;
                    else if (i % 2 == 0 | i % 3 == 0) ;
                    else
                    {
                        j = 5;
                        f = 1 > 0;
                        while (j * j <= i)
                            if (i % j++ == 0)
                                f = 1 < 0;
                        c += f ? 1 : 0;
                    }
                }
                return c;
            };

        Console.WriteLine("1 -> 0 : " + (s(1) == 0 ? "OK" : "FAIL"));
        Console.WriteLine("2 -> 1 : " + (s(2) == 1 ? "OK" : "FAIL"));
        Console.WriteLine("5 -> 3 : " + (s(5) == 3 ? "OK" : "FAIL"));
        Console.WriteLine("10 -> 4 : " + (s(10) == 4 ? "OK" : "FAIL"));
        Console.WriteLine("100 -> 25 : " + (s(100) == 25 ? "OK" : "FAIL"));
        Console.WriteLine("1,000 -> 168 : " + (s(1000) == 168 ? "OK" : "FAIL"));
        Console.WriteLine("10,000 -> 1,229 : " + (s(10000) == 1229 ? "OK" : "FAIL"));
        Console.WriteLine("100,000 -> 9,592 : " + (s(100000) == 9592 ? "OK" : "FAIL"));
        Console.WriteLine("1,000,000 -> 78,498 : " + (s(1000000) == 78498 ? "OK" : "FAIL"));
    }
}

Починає зайняти деякий час, коли ви перейдете понад 1 мільйон.


2

Матлаб, 60 байт

Продовжуючи прив’язаність до однолінійних функцій Matlab. Без використання вбудованої факторизації:

f=@(x) nnz(arrayfun(@(x) x-2==nnz(mod(x,[1:1:x])),[1:1:x]));

Зважаючи на те, що у простого числа yє лише два фактори [1,y]: ми підраховуємо числа в діапазоні, у [1,x]яких є лише два коефіцієнти.

Використання факторизації дозволяє значно скоротити (до 46 байт).

g=@(x) size(unique(factor(factorial(x))),2);

Висновок: Вам потрібно вивчити їхні мови для гри в гольф: D


2

Власне, 10 байт

Це найкоротше рішення, яке я знайшов, що не натрапив на помилки інтерпретатора на TIO. Пропозиції з гольфу вітаються. Спробуйте в Інтернеті!

;╗r`P╜>`░l

Ungolfing

         Implicit input n.
;╗       Duplicate n and save a copy of n to register 0.
r        Push range [0..(n-1)].
`...`░   Push values of the range where the following function returns a truthy value.
  P        Push the a-th prime
  ╜        Push n from register 0.
  >        Check if n > the a-th prime.
l        Push len(the_resulting_list).
         Implicit return.

2

Желе , 3 байти

ÆRL

Jelly має вбудовану функцію підрахунку простих лічильників ÆCта функцію головної перевірки ÆP, вона замість цього використовує вбудовану функцію генерації простих генерацій ÆRта приймає довжину L.

Я думаю, це приблизно настільки ж прикордонний, як і використання вбудованих простих факторів , які також займуть 3 байти !Æv( !факториальні, Ævрахуйте прості фактори)


2

PHP, 96 92 байт

for($j=$argv[1]-1;$j>0;$j--){$p=1;for($i=2;$i<$j;$i++)if(is_int($j/$i))$p=0;$t+=$p;}echo $t;

Збережено 4 байти завдяки Роману Гряфу

Тестуйте онлайн

Код тестування без вовків:

$argv[1] = 5;

for($j=$argv[1]-1;$j>0;$j--) {
    $p=1;
    for($i=2;$i<$j;$i++) {
        if(is_int($j/$i)) {
            $p=0;
        }
    }
    $t+=$p;
}
echo $t;

Тестуйте онлайн


Чому ви використовуєте, isInt(...)?1:0а не простоisInt(...)
Роман Гряф

@ RomanGräf Спасибі, ви праві. Я покинув тернар після багатого посилення коду, і це було настільки очевидно, що я не міг його побачити ...
Маріо,

2

APL (Dyalog Unicode) , 13 байт SBCS

2+.=0+.=⍳∘.|⍳

Спробуйте в Інтернеті!

ɩ ndices 1…
 N⧽ ∘.| решта таблиці (використовуючи ці дві як осі)
ɩ ndices 1… N

0+.= сума елементів, що дорівнює нулю (тобто скільки дільників має кожен)

2+.= сума елементів, що дорівнює двом (тобто скільки простих ліній)


2

Python 3, 40 байт

f=lambda n:1if n<1else(2**n%n==2)+f(n-1)

Непарне ціле число k є простим, якщо єдине, якщо 2 ** (k-1) збігається з 1 mod k. Таким чином, ми просто перевіряємо цю умову і додаємо 1 для випадку k = 2.


2 ** n% n == 2 недостатньо, як тест
першості

@RosLuP Ось чому в базовий випадок n == 0 слід додати 1 (для врахування випадку n = 2).
Sandeep Silwal

2 ** n% n == 2 недостатньо взагалі ... Існує багато (нескінченне, про що я б пам’ятав) цифр, де 2 ^ n% n = 2, які не є простими
буквами

Наприклад 341 = 11 * 31, але (2 ^ 341) mod 341 == 2
RosLuP

@RosLuP: Ага, так, я подивився. Ці цифри називаються Ферма-пседопрімес, але вони здаються досить рідкісними: P
Сандіп Сільваль,

2

MATL , 9 байт

Це дозволяє уникнути розкладання основного фактора. Його складність становить O ( n ²).

:t!\~s2=s

Спробуйте в Інтернеті!

:     % Range [1 2 ... n] (row vector)
t!    % Duplicate and transpose into a column vector
\     % Modulo with broadcast. Gives matrix in which entry (i,j) is i modulo j, with
      % i, j in [1 2 ... n]. A value 0 in entry (i,j) means i is divisible by j
~     % Negate. Now 1 means i is divisible by j
s     % Sum of each column. Gives row vector with the number of divisors of each j
2=    % Compare each entry with 2. A true result corresponds to a prime
s     % Sum

1

JavaScript (ES6), 50 + 2 46 + 2 43 байти

Збережено 3 5 байт завдяки Нілу:

f=n=>n&&eval(`for(z=n;n%--z;);1==z`)+f(n-1)

evalможе отримати доступ до nпараметра.
У eval(...)перевіряє , якщо nпервинно.


Попередні рішення:
Кількість байтів має бути +2, оскільки я забув назвати функцію f=(необхідну для рекурсії)

46 + 2 байти (збережено 3 байти завдяки ETHproductions):

n=>n&&eval(`for(z=n=${n};n%--z;);1==z`)+f(n-1)

50 + 2 байти:

n=>n&&eval(`for(z=${n};${n}%--z&&z;);1==z`)+f(n-1)

1
Принаймні, в моєму браузері evalможна отримати доступ до nпараметра до вашої функції (який ви забули назвати, коштувавши вам 2 байти; добре знати, що я не єдиний, хто робить цю помилку), що заощаджує вам 5 байт.
Ніл

@Neil я не знав eval. Тестований на firefox, хром та край, він працював на мене. Пояснення - це параметри eval () в контексті заяви . Два приклади: a=12;f=b=>eval('a + 5');f(8)дисплеї 17та a=12;f=a=>eval('a + 5');f(8)дисплеї 13.
Хеді

1

Java 7,102 байти

Груба сила

int f(int n){int i=2,j=2,c=1,t=0;for(;i<=n;j=2,c+=t==1?1:0,i++)for(;j<i;t=i%j++==0?j=i+1:1);return c;}

Безумовно

int f(int n){
int i=2,j=2,c=1,t=0;
for(;i<=n;j=2,c+=t==1?1:0,i++)
    for(;j<i;)
        t=i%j++==0?j=i+1:1;
    return c;
 }

Наразі це дає неправильний результат для введення даних 1. Зараз він повертається 1замість 0. Ви можете виправити це, або зміни return c;до return n<2?0:c;або зміни ,c=1,до ,c=n<2?0:1,.
Кевін Круїссен


1

Власне, 10 байт

Якщо моя перша відповідь фактично заборонена для використання функції, що генерує основну функцію, ось резервна відповідь за допомогою теореми Вілсона. Пропозиції з гольфу вітаються. Спробуйте в Інтернеті!

R`;D!²%`MΣ

Спробуйте в Інтернеті

         Implicit input n.
R        Push range [1..n]
`...`M   Map the following function over the range. Variable k.
  ;        Duplicate k.
  D        Decrement one of the copies of k.
  !²       Push ((k-1)!)².
  %        Push ((k-1)!)² % k. This returns 1 if k is prime, else 0.
Σ        Sums the result of the map, adding all the 1s that represent primes, 
          giving the total number of primes less than n.
         Implicit return.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.