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

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 для не простых.

XNOR
источник
Вычисление факториала снизу вверх - это отличный трюк. +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

Три байта сохранены благодаря гениальному решению Дениса

DJMcMayhem
источник
Короче использовать функцию «экспоненты простой факторизации», потому что она векторизируется: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}}}является фактором , чтобы проверить.

DuhHello
источник
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, либо превышен, либо не хватает памяти.

Ссылки:

Генератор дальности Мартина

Первоклассная проверка Мартина

mbomb007
источник
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)

(Я не могу опубликовать это где-либо, потому что это число простое? Принимает только полные программы ...)

Тестовый фрагмент

ETHproductions
источник
Вау ... мне понадобилось время, чтобы понять. Хорошая работа!
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циклах.

AdmBorkBork
источник
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

CJam , 7 байтов

rim!mF,

Попробуйте онлайн! Использует функцию факторизации.

Объяснение:

ri      | read input as integer
  m!    | take the factorial
    mF  | factorize with exponents (one element per prime)
      , | find length
Линус
источник
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 да вы правы, но я дал только часть функции, которая не компилируется самостоятельно
Ариэль Береславский
@tfbninja На самом деле это не так.
Эрик Outgolfer
круто звучит хорошо!
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 миллион.

Yodle
источник
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

ptev
источник
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.
Sherlock9
источник
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;
 }
Numberknot
источник
В настоящее время это дает неверный результат для ввода 1. В настоящее время возвращается 1вместо 0. Вы можете исправить это, либо изменения return c;к return n<2?0:c;или изменения ,c=1,к ,c=n<2?0:1,.
Кевин Круйссен
1

q 35 байт

{sum 1=sum'[0=2_' a mod\: a:til x]}
Рувим Тейлор
источник
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.
Sherlock9
источник