介绍
质数计数函数,也称为Pi函数返回小于或等于x的质数。
挑战
您的程序将采用一个可以假定为正数的整数x,并输出一个等于或小于x的素数的整数。这是一个代码高尔夫挑战,因此获胜者将是字节数最少的程序。
您可以使用选择的任何语言,只要它在挑战开始之前就已经存在,但是如果该语言具有内置的素数计数功能或素数检查功能(例如Mathematica),则该功能不能在您的代码中使用。
输入示例
输入:
1
输出:
0
输入:
2
输出:
1
输入:
5
输出:
3
质数计数函数,也称为Pi函数返回小于或等于x的质数。
您的程序将采用一个可以假定为正数的整数x,并输出一个等于或小于x的素数的整数。这是一个代码高尔夫挑战,因此获胜者将是字节数最少的程序。
您可以使用选择的任何语言,只要它在挑战开始之前就已经存在,但是如果该语言具有内置的素数计数功能或素数检查功能(例如Mathematica),则该功能不能在您的代码中使用。
输入:
1
输出:
0
输入:
2
输出:
1
输入:
5
输出:
3
Answers:
!fg
这假定允许分解内置。在线尝试!
! Compute the factorial of the input.
f Determine its unique prime factors.
g Get the length of the resulting list.
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。
:pYFn
我写了一个版本,对MATL矩阵的工作方式进行了非常酷的解释:
但这不再相关。如果要查看修订历史,请查看它。
新的解释:
:p % Compute factorial(input)
YF % Get the exponenents of prime factorization
n % Get the length of the array
丹尼斯的天才解决方案节省了三个字节
YF!s1=s
感谢@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
ÆE
,因为每个指数对应一个不同的素数。RÆESL
做到这一点。!ÆEL
会更短。
{{#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}}}
是检查的因素。
不使用任何内置的素函数
得益于@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)
%þ`¬Sċ2
使用余数表获得7个字节。
ḍþḅ1ċ2
保存一个字节。
Ḷ!²%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.
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);
}
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"));
}
}
一旦超过一百万,开始需要一段时间。
这是我发现的最短的解决方案,没有遇到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.
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(...)
f=lambda n:1if n<1else(2**n%n==2)+f(n-1)
仅当2 **(k-1)与1 mod k一致时,奇数整数k是素数。因此,我们仅检查此条件,并在k = 2的情况下加1。
这避免了素因分解。它的复杂度为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
感谢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)
eval
可以访问n
函数的参数(您忘记命名该参数,花费2个字节;很高兴知道我不是唯一一个犯此错误的人),它可以节省5个字节。
eval
。经过Firefox,镀铬和边缘测试,对我有用。解释是eval()在语句上下文中解析。两个示例:a=12;f=b=>eval('a + 5');f(8)
display 17
和a=12;f=a=>eval('a + 5');f(8)
display 13
。
蛮力
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,
。
如果我的第一个“实际答案”不被允许使用质数生成函数,这是使用威尔逊定理的备用答案。欢迎打高尔夫球。在线尝试!
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.