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


28

Введение

Функция подсчета простых чисел , также известная как функция Pi , возвращает количество простых чисел, меньших или равных x.π(Икс)

Вызов

Ваша программа возьмет целое число x, которое вы можете считать положительным, и выведите одно целое число, равное количеству простых чисел, меньших или равных x. Это соревнование по , поэтому победителем станет программа с наименьшим количеством байтов.

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

Пример входов

Вход:
1
Выход:
0

Вход:
2
Выход:
1

Вход:
5
Выход:
3

A000720 - OEIS


3
Как насчет других простых функций? Например, функция «следующего прайма»
Луис Мендо,

6
как насчет простых функций факторизации?
Maltysen

4
Добро пожаловать в программирование головоломок и Code Golf!
Аднан

6
Как сказал Аднан, добро пожаловать в PPCG! Для будущих испытаний позвольте мне порекомендовать Песочницу, где вы можете опубликовать запрос, чтобы получить содержательный отзыв и критику, прежде чем публиковать его на главном сайте.
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
Черт, я получаю рект на своем родном языке во второй раз, ха-ха. +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%k1 для простых чисел и 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

Преуспевать. Я передам это Желе для практики :-)
Луис Мендо,

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
@ Деннис Спасибо! Я использовал первое предложение. Второй слишком отличается, и это ваш подход
Луис Мендо

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

Расположен в стиле Лисп:

{{#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 33-байтовой функции простоты (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);}

Ungolfed

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

Баш + coreutils, 30

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

Ideone.


Пакет Bash + coreutils + BSD-games, 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

Matlab, 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

У желе есть встроенная функция подсчета Æ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 Спасибо, вы правы. Я покинул троицу после большого количества кодов, и это было настолько очевидно, что я не мог этого увидеть ...
Mario

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

@RosLuP Вот почему базовый случай n == 0 должен добавить 1 (для учета случая n = 2).
Сандип Сильвал

2 ** n% n == 2 в общем случае недостаточно ... Существует много (бесконечно много в том, что я запомнил бы) чисел, где 2 ^ n% n = 2, которые не являются простыми числами
RosLuP

Например, 341 = 11 * 31, но (2 ^ 341) мод 341 == 2
РосЛюП

@RosLuP: Ах, да, я посмотрел. Эти числа называются Fermat Psuedoprimes, но они, по-видимому, встречаются довольно редко: P
Sandeep Silwal

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 байта благодаря продуктам ETH):

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 байтов.
Нил

@ Нейл, я не знал для eval. Протестировано с Firefox, Chrome и Edge это сработало для меня. Объяснение: 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;}

Ungolfed

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.