这是我的第一个高尔夫问题代码,也是一个非常简单的问题,因此,如果我可能违反了任何社区准则,我事先表示歉意。
任务是按升序打印所有小于一百万的质数。输出格式应为每行输出一个数字。
与大多数代码高尔夫球提交一样,其目的是最小化代码大小。针对运行时进行优化也是一个奖励,但它是次要目标。
10^6
更短;)
1e6
:-D
这是我的第一个高尔夫问题代码,也是一个非常简单的问题,因此,如果我可能违反了任何社区准则,我事先表示歉意。
任务是按升序打印所有小于一百万的质数。输出格式应为每行输出一个数字。
与大多数代码高尔夫球提交一样,其目的是最小化代码大小。针对运行时进行优化也是一个奖励,但它是次要目标。
10^6
更短;)
1e6
:-D
Answers:
只是为了比较:
Prime@Range@78498
正如评论中指出的那样,我未能为每行提供一个素数。更正:
Column@Prime@Range@78498
Prime~Array~78498
也是17 :)
Print/@
和终止;
以防止输出较长的Null
s修订列表,但要花8个额外字符。
SEG-FAULT
打印后得到881
-O3
可以gcc
解决问题!!
n=2;main(m){n<1e6&&main(m<2?printf("%d\n",n),n:m-++n%m);}
不幸的是,这是一行输出:
primes(1000000)
但这可以通过一个简单的矩阵转置来解决:
primes(1000000)'
并且我可以使用指数表示法(如注释中建议的那样)切出一些字符:
primes(1e6)'
1e6
代替而不是1000000
帮助。
'
在端部
seq 2 1e6|factor|sed 's/.*: //g;/ /d'
seq 2 1000000|factor|sed -e 's/[0-9]*: //g' -e '/^.* .*$/ d'
在我的计算机上(2.0 GHz CPU,2 GB内存)需要14秒。
seq 2 1000000|factor|sed 's/[0-9]*: //g;/^.* .*$/ d'
seq 1e6|factor|awk '$0=$2*!$3'
有点短。
c p
c是与cat的符号链接,而p是素数最大为一百万的文本文件...您可以使用shell内置函数来做到这一点吗?
由于saeedn不会按照我的建议行事-比他的方法短而且快-我想我会发表自己的答案:
seq 1e6|factor|awk '$0=$2*!$3'
seq 1e6
列出所有不超过1,000,000的正整数。
factor
将它们一一分解。对于前十个,输出如下:
1:
2: 2
3: 3
4: 2 2
5: 5
6: 2 3
7: 7
8: 2 2 2
9: 3 3
10: 2 5
最后,
awk '$0=$2*!$3'
将整行($0
)更改为第二个字段(第一个素数)和第三个字段的逻辑取反的乘积(1
如果等于或小于一个素数,0
则否则)。
这会将与素数相对应的行替换为数字本身,并将所有其他行替换为零。由于awk仅打印真实值,因此只会打印质数。
awk '$0=$2*!$3'
太酷了!
require'mathn'
p (2..1e6).select &:prime?
require'prime';p Prime.take 78498
。
如果可以的话,还会打高尔夫吗?
多数情况下,这是试图解析factor
尴尬的输出格式。
seq 1e6|factor|grep -oP "(?<=: )\d+$"
在我的计算机上完成需要5.7秒左右的时间。
(碰巧我的帖子是第一页出现在答案的第二页上,所以没人会看到它……)
这会更长,更慢(耗时10秒)。
seq 1e6|factor|egrep ':.\S+$'|grep -oE '\S+$'
factor
,但是coreutils就在那里!
seq 1e6|factor|grep -oP "(?<=: )\d+$"
用Perl的grep的回顾后
-P
启用perl样式的正则表达式。 (?<=: )
是字符串“:” 的正向后缀。基本上说“:”必须在匹配项之前\d+$
,但实际上不是匹配项的一部分,因此该-o
选项只给我们一个冒号后面的匹配数,即仅给出只有一个因数(即质数)的数字。
mapM print [n|n<-[2..10^6],all((>0).rem n)[2..n-1]]
mapM_
为mapM
,不打印返回值,这就是Code Golf。;)
正则表达式功夫:)
for(1..1E6){(1x$_)=~/^(11+?)\1+$/ or print"$_\n"}
非高尔夫版本:
for(1 .. 1_000_000) {
(1x$_) =~ /^(11+?)\1+$/ or print "$_\n";
}
在我输入此信息时,它甚至还没有取得10%的进步!
正则表达式的来源:http : //montreal.pm.org/tech/neil_kandalgaonkar.shtml
1000000
可以写成10**6
我不能相信这一掌数学(即使它只是一个由2个字符)
a#~1 p:a=:i.1e6
要么:
p:i.78498
... The output format should be one number per line of output.
这就是为什么我的答案始于1[\
。
n(6?,:|2>{(.p|%-.}do:n
为了提高速度,可以将代码缩短两个字节:
n(6?,:|2>.{|%2>-}/n*
如果忽略了在已编辑问题中指定的输出格式(许多现有答案都这样做),则可以在快速版本中保存两个字节,而在慢速版本中保存一个字节:
n(6?,:|2>{(.p|%-.}do
n(6?,:|2>.{|%2>-}/`
对于快速版本,这将在素数之后打印一个附加的LF,并将较慢的素数作为数组打印。
这两个版本都是Eratosthenes筛子的实现。
快速版本执行以下操作:
设置A = [ 2 3 4 … 999,999 ]
和| = [ 0 1 2 … 999,999 ]
。
设置N = A[0]
并打印N
。
从收集每第N个元件|
在C
。这些是的倍数N
。
设置A = A - C
。
如果A
为非空,请返回2。
n(6? # Push "\n".pop() ** 6 = 1,000,000.
,:| # Push | = [ 0 1 2 … 999,999 ].
,2> # Push A = [ 2 3 4 … 999,999 ].
{ #
( # Unshift the first element (“N”) of “A”.
.p # Print “N”.
|% # Collect every N-th element from “A” into a new array, starting with the first.
- # Take the set difference of “A” and the array from above.
. # Duplicate the set difference.
}do # If the set difference is non-empty, repeat.
:n # Store the empty string in “n”, so no final LF will get printed.
慢速版本以类似的方式工作,但不是连续删除最小的“ A”的倍数(始终为质数),而是删除小于1,000,000的所有正整数的倍数。
在没有任何内置的数学函数可分解或检查素数的情况下,所有的GolfScript解决方案要么很大要么效率很低。
尽管距离效率还差得很远,但我认为我已经达到了不错的速度尺寸比。在提交该方法时,这种方法似乎是不使用任何上述内置方法的方法中最短的方法。我说似乎是因为我不知道某些答案的工作方式...
我已经对所有四个提交的GolfScript解决方案进行了基准测试:w0lf(试验部门),我的其他答案(Wilson定理)和这个答案中的两个。结果是:
Bound | Trial division | Sieve (slow) | Wilson's theorem | Sieve (fast)
----------+--------------------+--------------------+------------------+----------------
1,000 | 2.47 s | 0.06 s | 0.03 s | 0.03 s
10,000 | 246.06 s (4.1 m) | 1.49 s | 0.38 s | 0.14 s
20,000 | 1006.83 s (16.8 m) | 5.22 s | 1.41 s | 0.38 s
100,000 | ~ 7 h (estimated) | 104.65 (1.7 m) | 35.20 s | 5.82 s
1,000,000 | ~ 29 d (estimated) | 111136.97s (3.1 h) | 3695.92 s (1 h) | 418.24 s (7 m)
10 6?,{:x,{)x\%!},,2=},`
旧代码:
10 6?,{.,{)\.@%!},,2=*},`
该代码仅具有理论价值,因为它非常慢且效率低下。我认为可能要花几个小时才能运行。
如果要测试,请尝试仅使用最多100的素数:
10 2?,{:x,{)x\%!},,2=},`
\;
为来保存字符*
。(通过查找第一个除数而不是全部除数,您也可以更快地获得当前字符数:10 6?,2>{.),2>{1$\%!}?=},`
.,
与:x,
和\.@
用x\
(空格是因为在评论与MD逃避问题),并删除*
。
!10 6?,2>{.(@*.)@%!},n*\;
如果忽略了在已编辑问题中指定的输出格式,则可以保存一个字节:
!10 6?,2>{.(@*.)@%!},`\;
这将素数作为数组打印(就像许多其他解决方案一样),而不是每行打印一个。
一般的想法是使用威尔逊定理,该定理指出当且仅当n > 1为素数
! # Push the logical NOT of the empty string (1). This is an accumulator.
10 6? # Push 10**6 = 1,000,000.
,2> # Push [ 2 3 4 … 999,999 ].
{ # For each “N” in this array:
.( # Push “N - 1”.
@ # Rotate the accumulator on top of the stack.
* # Multiply it with “N - 1”. The accumulator now hold “(N - 1)!”.
.) # Push “(N - 1)! + 1”
@ # Rotate “N” on top of the stack.
%! # Push the logical NOT of “((N - 1)! + 1) % N”.
}, # Collect all “N” for which “((N - 1)! + 1) % N == 0” in an array.
n* # Join that array by LF.
\; # Discard the accumulator.
比审判部门快,但比Eratosthenes筛子慢。看到我的其他答案。
void x(){for(int i=1;i++<1e6;)System.out.print(new String(new char[i]).matches(".?|(..+?)\\1+")?"":(i+"\n"));}
通过正则表达式使用一元除法作为素数测试。
main(i,j,b){for(;i++<1e6;b++&&printf("%d\n",i))for(j=2;j<i;)b=i%j++&&b;}
该算法效率极低,但是由于我们正在执行代码高尔夫球,所以这无关紧要。
main(i,j,b){for(;i++<1e6;b++&&printf("%d\n",i))for(j=2;j<i;)b=i%j++&&b;}
或类似这样的想法(因为我实际上没有编译它)
i
确定为0?我认为,如果您提供任何论点,它将失败。另外,我认为j
会出现某种类型的错误。b
虽然不确定。
for(i in 2:1e6)if(sum(!i%%2:i)<2)cat(i," ")
对于从2到1e6的每个数字x,如果x mod 2到x的x等于0的数量小于2,则只需输出。
Enumerable.Range(1,1e6).Where(n=>Enumerable.Range(2,n).All(x=>x%n!=0))
你不会在这里看到很多东西了...
double
1e6
为an int
,但是int
是必需的Range
。(2)内部Range
必须使用最多的n-2
术语,否则您将测试n % n
清楚0
。(3)x%n
在需要时写n%x
。解决这些问题后,类似的方法将起作用:Enumerable.Range(2,999999).Where(n=>Enumerable.Range(2,n-2).All(x=>n%x!=0))
但是,这仍然不会输出数字。要求是每行一个。