Answers:
有效答案。使用威尔逊定理。
.f%h.!tZZQ
使用内置函数进行素数分解,而不是素数检查。
.ftPZQ
.f Q First n that passes filter of lambda Z, uses input for how many
t Tail. This makes all that have len-one prime factorization become empty list, and thus falsey.
P Prime factorization - primes have a len-one factorization.
Z Lambda var
因为你能。
\newcount\a\newcount\b\newcount\c\newcount\n\newcount\p\newcount\q\let\v\advance\let\e\else\let\z\ifnum
\def\d#1:#2:#3:{\z#1>#2\v#1 by-#2\d#1:#2:#3:\e\z#1=#2#3=1\e#3=0\fi\fi}
\def\i#1:#2:#3:{#3=0\z#1>#2\a=#1\d\a:#2:\c:
\z\c=0\b=#2\v\b by 1\i#1:\the\b:#3:\e#1\par\fi\e#3=1\fi}
\def\l#1:#2:#3:#4:{\i\the#1:2:#4:
\z#4=0\v#2 by 1\fi\z#2<#3\v#1 by 1\l#1:#2:#3:#4:\fi}
\l\p:\n:10:\q:\end
最后一行中的数字是您想要的复合数字的数量。
这是一个简单的除数测试器。\d
检查是否#2
分开#1
。\i
调用 \d
所有可能的分频器(即< #1
)。\l
列出返回0 的第一个#2
数字\i
。
非高尔夫(很好,半高尔夫)版本:
\newcount\a
\newcount\b
\newcount\c
\newcount\n
\newcount\p
\newcount\q
\def\div#1:#2:#3:{%
\ifnum#1>#2 %
\advance#1 by-#2 %
\div#1:#2:#3:%
\else%
\ifnum#1=#2 %
#3=1%
\else%
#3=0%
\fi%
\fi%
}
\long\def\isprime#1:#2:#3:{%
#3=0%
\ifnum#1>#2 %
\a=#1 %
\div\a:#2:\c: %
\ifnum\c=0 %
\b=#2 %
\advance\b by 1 %
\isprime#1:\the\b:#3:%
\else
#1\par%
\fi%
\else%
#3=1%
\fi%
}
\def\listprimes#1:#2:#3:#4:{%
\isprime\the#1:2:#4: %
\ifnum#4=0 %
\advance#2 by 1 %
\fi
\ifnum#2<#3 %
\advance#1 by 1 %
\listprimes#1:#2:#3:#4: %
\fi
}
\listprimes\p:\n:11:\q:
\end
lambda n:sorted({(k/n+2)*(k%n+2)for k in range(n*n)})[:n]
少打高尔夫球:
def f(n):
R=range(n)
return sorted({(a+2)*(b+2)for a in R for b in R})[:n]
这个想法是通过将除0和1以外的所有自然数对相乘来生成一组复合数。然后,对该集合进行排序,并采用第一个n
元素。将集合的笛卡尔积{2, 3, ..., n+2}
与自身结合就足够了,我们可以通过上移range(n)
2 来获得。
为了打高尔夫球,我们做了一个经典的高尔夫技巧,将两个值作为一个值存储(a,b)
在中,然后将其提取为。range(n)
k
range(n*n)
a=k/n, b=k%n
i->{int a[]=new int[i],c=3,k=0,d;for(;k<i;c++)for(d=c;d-->2;)if(c%d<1){a[k++]=c;break;}return a;}
扩展,带有样板:
public class C {
public static void main(String[] args) {
Function<Integer, int[]> f = i -> {
int a[] = new int[i], c = 3;
for (int k = 0; k < i; c++) {
for (int d = c; d --> 2;) {
if (c % d < 1) {
a[k++] = c;
break;
}
}
}
return a;
};
System.out.println(Arrays.toString(f.apply(5)));
}
}
li_5*{_,2>f%0&},<`
不使用任何内置的素数或分解运算符。蛮力检查数字是否合成。
这里使用的一个观察结果是,我们可以轻松地计算出要测试的数字的安全上限。由于每个大于4的第二个数字都是合成的,因此它4 + n * 2
是第n个合成数字的上限。
根据@Dennis的建议,最新的实现实际上使用n * 5
了上限,虽然效率较低,但要短2个字节。
说明:
li Get and convert input.
_ Copy, will need the value to trim the list at the end.
5* Calculate upper bound.
{ Start of filter.
_ Copy value.
, Create list [0 .. value-1].
2> Slice off the first two, leaving candidate factors [2 .. value-1].
f% Apply modulo with all candidate factors to value.
0& Check if one of the modulo results is 0.
}, End of filter.
< Trim output to n values.
` Convert list to string.
n=>{r=[];for(q=2;r.length!=n;++q)if(/^(..+)\1+$/.test("-".repeat(q)))r.push(q);return r}
f=
是合法的。
n=>eval('for(r=[],q=2;r.length-n;/^(..+)\\1+$/.test("-".repeat(++q))&&r.push(q))r')
n&&!r[n-1]
:'| 它的长度与r.length<n
–短一个字符r.length!=n
–相同,但是应该是Code Golf,对吗?:-]
(`take`[x|x<-[4..],or[mod x y<1|y<-[2..x-1]]])
用法示例:
*Main> (`take`[x|x<-[4..],or[mod x y<1|y<-[2..x-1]]]) 13
[4,6,8,9,10,12,14,15,16,18,20,21,22]
怎么运行的
[x|x<-[4..] ] -- keep all x from the integers starting with 4 where
,or -- where at least one element of the following list is "True"
[mod x y<1|y<-[2..x-1]] -- "x mod y < 1" for all y from [2,3,...x-1]
(`take`[ ]) -- take the first n elements from the xes
-- where n is the parameter supplied when calling the function
fun n->(Array.filter(fun i->Seq.exists((%)i>>(=)0)[2..i-1])[|2..n*n|]).[..n-1]
解释:
fun n->
[|2..n*n|] // Generate an array of integers from 2 to n * n
Array.filter(fun i-> ) // Filter it using the following function on each element
[2..i-1] // Generate a list of possible divisors (from 2 to i-1)
Seq.exists( ) // Check if at least one of the divisors is valid, that is
(%)i>>(=)0 // That i % it is equal to 0. This is equivalent to (fun d -> i % d = 0)
( ).[..n-1] // Take the n first elements of the resulting, filtered array
i
两次使用变量有点令人困惑。我对F#不太熟悉,但是您也许不能使用j
?
int main(){int n,i,x=4;cin>>n;while(n){for(i=2;i<x-1;i++){if(x%i==0){cout<<x<<' ';n--;break;}}x++;}return 0;}
不打高尔夫球
int main(){
int n,i,x=4;cin>>n;
while(n)
{
for(i=2;i<x-1;i++)
{
if(x%i==0){cout<<x<<' ';n--;break;}
}
x++;
}
return 0;
}
while
的for
。
n->(n>0&&println(4);n>1&&(i=0;c=big(6);while i<n-1 mod(factorial(c-1),c)<1&&(i+=1;println(c));c+=1end))
这使用了威尔逊定理。
取消高尔夫:
function f(n::Int)
# Always start with 4
n > 0 && println(4)
# Loop until we encounter n composites
if n > 1
i = 0
c = big(6)
while i < n-1
if mod(factorial(c-1), c) == 0
i += 1
println(c)
end
c += 1
end
end
end
n=>eval('for(a=[],x=4;n&&!a[~-n];x++)for(y=2;y*2<=x;)if(x%y++<1){a.push(x);break}a')
该函数返回第一个n
复合数字的数组。
~-n
是一种奇特的写作方式n-1
; 长度相同,但更有趣,对吗?
我使用的唯一原因eval
是模板n=>eval('...returnValue')
比短1个字符n=>{...return returnValue}
。
n=>eval('for(a=[],x=4;n&&!a[~-n];x++){for(z=0,y=2;y*2<=x;)if(x%y++<1)z=1;if(z)a.push(x)}a')
n=>eval('for(a=[],i=4;a.length<n;i++)if((x=>{for(y=2,z=1;y*2<=x;)if(x%y++<1)z=0;return!z})(i))a.push(i);a')
0 -> []
1 -> [4]
2 -> [4, 6]
3 -> [4, 6, 8]
13 -> [4, 6, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 22]
受到Nimi早前的回答的启发,将谓词替换为短2字节的谓词,该谓词基于any
无点lambda而不是嵌套列表推导。
(`take`[x|x<-[4..],any((<)1.gcd x)[2..x-1]])
说明:
[x|x<-[4..], -- consider all integers x >=4
[2..x-1] -- consider all integers smaller than x
any((<)1.gcd x) -- if for any of them
(<)1 -- 1 is smaller than
.gcd x -- the gcd of x and the lambda input
-- then we found a non-trivial factor and thus the number is composite
(`take`[ ]) -- take the first <argument> entries