素数计数功能


28

介绍

数计数函数,也称为Pi函数πX返回小于或等于x的质数。

挑战

您的程序将采用一个可以假定为正数的整数x,并输出一个等于或小于x的素数的整数。这是一个挑战,因此获胜者将是字节数最少的程序。

您可以使用选择的任何语言,只要它在挑战开始之前就已经存在,但是如果该语言具有内置的素数计数功能或素数检查功能(例如Mathematica),则该功能不能在您的代码中使用。

输入示例

输入:
1
输出:
0

输入:
2
输出:
1

输入:
5
输出:
3

A000720-OEIS


3
其他与素数相关的功能呢?例如,“下一个主要”功能
Luis Mendo

6
素因数分解函数呢?
Maltysen '16

4
欢迎来到编程难题和Code Golf!
阿德南

6
正如Adnan所说,欢迎来到PPCG!对于未来的挑战,让我推荐一个沙盒,您可以在其中发布挑战,以在发布到主站点之前获得有意义的反馈和批评。
AdmBorkBork

我认为这是@TheBikingViking想要链接的内容:相关
mbomb007 '09

Answers:


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'9

5
该死,我第二次用自己的语言说话。+1
阿德南

为什么这样做?
奥利弗·尼

1
@Oliver由于阶乘Ñ是由所有整数整除1,...,N(特别是素数P≤Ñ),并通过没有其它原Q>Ñ,因为它不能被表示为更小的数的乘积。
丹尼斯

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)!^2p%k素数为1,非素数为0。


从头开始计算阶乘是一个绝妙的技巧。+1
ETHproductions 2016年

6

MATL11,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
Luis Mendo

@LuisMendo这是一种完全不同的方法,请随时进行发布。(尽管您不愿意,但我很乐意)
DJMcMayhem

前进。我会将其移植给Jelly练习:-)
Luis Mendo

5

果冻8 5字节

感谢@Dennis,节省了3个字节!

RÆESL

在线尝试!

DJMcMayhem的MATL答案(先前版本)的端口由Dennis改进。

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
更正:路易斯·门多(Luis Mendo)的港口:DJMcMayhem的MATL答案。:P
DJMcMayhem

2
您只需要结果的最大长度ÆE,因为每个指数对应一个不同的素数。RÆESL做到这一点。!ÆEL会更短。
丹尼斯

1
@丹尼斯谢谢!我用了第一个建议。第二个太不同了,这是您的做法
Luis Mendo

5

具有ParserFunctions的 MediaWiki模板,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但这没关系,op要求仅支持正整数。




4

果冻13 11 10 9 8 7 6 个字节

不使用任何内置的素函数
得益于@miles(使用表),-
1字节得益于@Dennis得-1字节(从一元转换为除数)

ḍþḅ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
您可以%þ`¬Sċ2使用余数表获得7个字节。
英里

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字节素数函数的修改(@Neil保存了1个字节,@ Arnauld保存了2个字节):

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

(我无法在任何地方发布此信息,因为此数字是素数吗?仅接受完整程序...)

测试片段


哇...花了我一段时间才明白。不错的工作!
todeale

不幸的是,它不适用于您的答案,但是您可能会&在素数函数的中间得到一个答案。
尼尔2016年

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++计数器。前面有一些额外的逻辑,用于考虑边沿案例的输入12,这是因为篱笆墙在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

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

不打高尔夫球

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是的,但是我只给出了函数的一部分,它不是自己编译的
Ariel Bereslavsky


很酷的声音!
FantaC


2

Bash + coreutils,30岁

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

Ideone。


Bash + coreutils + BSD游戏包,22

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

这个简短的答案要求您安装了bsdgames软件包:sudo apt install bsdgames


2

Pyke,8个 6字节

SmPs}l

在这里尝试!

感谢Maltysen的新算法

SmP    -    map(factorise, input)
   s   -   sum(^)
    }  -  uniquify(^)
     l - len(^)

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"));
    }
}

一旦超过一百万,开始需要一段时间。


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

开球

         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并采用length 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;

感谢RomanGräf,节省了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äf16

@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)

仅当2 **(k-1)与1 mod k一致时,奇数整数k是素数。因此,我们仅检查此条件,并在k = 2的情况下加1。


2 ** n%n == 2作为
初步

@RosLuP这就是为什么n == 0的基本情况应该加1(以解决n = 2情况)。
Sandeep Silwal,

2 ** n%n == 2通常是不够的...存在许多(我记得是无限的)数字,其中2 ^ n%n = 2 不是素数
RosLuP

例如341 = 11 * 31但(2 ^ 341)mod 341 == 2
RosLuP

@RosLuP:好的,我查了一下。这些数字称为Fermat Psuedoprimes,但它们似乎非常罕见:P
Sandeep Silwal,

2

MATL,9个字节

这避免了素因分解。它的复杂度为O(ñ ²)。

: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字节

感谢Neil,节省了3 5个字节:

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

eval可以访问n参数。
eval(...)如果检查n是首要。


先前的解决方案:
字节数应为+2,因为我忘记命名该函数了f=(需要递归)

46 + 2个字节(由于ETHproductions,节省了3个字节):

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)display 17a=12;f=a=>eval('a + 5');f(8)display 13
Hedi 2016年

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

当前,这为input给出了错误的结果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.
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.