Answers:
感谢xnor提出了一些节省3个字节的更改建议!
f n=[m|m<-[1..],all((>0).mod(n+m))[2..n+m-1],all((/=m).f)[1..n-1]]!!0
我是Haskell的新手,并且Haskell打高尔夫球,反馈非常感谢!
我们定义一个函数f n
。我们定义f n
为!!0
列表的第一个元素:
[m|m<-[1..],all((>0).mod(n+m))[2..n+m-1],all((/=m).f)[1..n-1]]
细分为:
[m| # Numbers m
m<-[1..], # From the integers greater than 0
all # Forall x
(>0).mod(n+m)# n+m mod x is not zero
[2..n+m-1] # from the integers from 2 to n+m-1
all # Forall
((/=m).f) # when f is applied the result is not m
[1..n-1] # from the integers from 1 to n-1
[2,3..]
可以只是[2..]
由1计数是默认的。有一个内置的notElem
。
notElem
但是第一个技巧是有帮助的,我将确保第二个技巧留在我的后兜里。
f 1
误,应该为
Rɓ²R+⁸ÆPTḟḢṭµ/Ṫ
假定A083569(n)≤n²(该序列似乎呈线性增长)。
Rɓ²R+⁸ÆPTḟḢṭµ/Ṫ Main link. Argument: n
R Range; yield [1, ..., n].
ɓ Begin a dyadic chain with swapped arguments.
µ/ Reduce the range by that chain.
If we call the chain f, this computes f(2,1), then f(3,f(2,1)),
then f(4,f(3,f(2,1)), etc.
The left argument is an integer k, the right one an array A.
² Square; yield k².
R Range; yield [1, ..., k²].
+⁸ Add k, yielding [1+k, ..., k²+k].
ÆP Test each sum for primality.
T Truth; get all indices of 1‘s. This finds all m in [1, ..., k²]
such that m+k is prime.
ḟ Filterfalse; remove all resulting elements that appear in A.
Ḣ Head; extract the first remaining result.
ṭ Tack; append the extracted integer to A.
This computes the first n elements of the sequence.
Ṫ Tail; extract the last, n-th element.
A083569(n)
至多n
第一个素数大n
于其定义的2n
第一个素数,至多为第一个素数,(对于n≥3
)小于4n*log(n)
Rosser-Schoenfeld的结果。
n=>{if(n<2)return 1;var p=new int[n-1];int i=0,j,s;for(;i<n-1;)p[i]=f(++i);for(i=1;;i++){for(j=2,s=i+n;j<s&&s%j++>0;);if(j==s&!System.Array.Exists(p,e=>e==i))return i;}}
到目前为止,最没有效率的方式计算出结果,所以从计算请切莫f(n)
对n>=30
这个代码。第一步是递归计算从f(1)
到的值f(n-1)
,然后f(n)
通过搜索第一个i
(即n+i
素数i
且不在先前值列表中)的第一个进行计算。
我是打高尔夫球的新手,因此非常感谢您提供意见/反馈。
注意:这是针对机器代码长度(而非源长度)优化的。
0: 89 f8 ff cf 74 32 97 89 fe 89 f1 ff c6 89 f0 99
1: f7 f1 85 d2 e0 f7 85 c9 75 ed 89 f9 ff c9 56 29
2: fe 56 57 51 89 fc e8 d3 ff ff ff 59 5f 5e 39 c6
3: e0 ef 96 5e 74 d1 c3
使用标准约定(即eax中的返回值,edi中的第一个参数,除ebx以外的所有调用者保存的寄存器)定义一个函数,该函数采用无符号的32位整数并返回最小的m等。
资源:
.globl a083569
// edi = original, probably don't touch
// esi = candidate prime, if it's not a repeat we return edi-this
a083569:
mov %edi, %eax
dec %edi
jz end
xchg %eax, %edi
mov %edi, %esi
primecheck:
mov %esi, %ecx
inc %esi
primeloop:
mov %esi, %eax
cdq
div %ecx
test %edx, %edx
loopnz primeloop
/* end */
// if esi isn't prime, then ecx is now one or greater.
test %ecx, %ecx
jnz primecheck
// esi is now our target prime: check if it's not already one
mov %edi, %ecx
dec %ecx
push %rsi /* we need a flag-safe way to restore this later */
sub %edi, %esi
chkdup:
push %rsi
push %rdi
push %rcx
mov %ecx, %edi
call a083569
pop %rcx
pop %rdi
pop %rsi
cmp %eax, %esi
loopne chkdup
/* end loop - chkdup */
xchg %esi, %eax
pop %rsi
je primecheck
/* end outer loop - primecheck */
end:
ret
#(loop[r[0 1]i 1](if(= i %)(last r)(recur(conj r(nth(for[j(range):when(=((set r)j)(seq(for[k(range 2(+ 1 i j)):when(=(mod(+ 1 i j)k)0)]j)))]j)0))(inc i))))
这可能仍然有些麻烦,我不太满意,(+ 1 i j)
但这是处理基本情况n = 1
和其余情况的最简单方法。((set r)j)
返回nil
如果j
不在集,(seq ())
在一个空列表返回nil为好。n = 1000
在48秒内计算。
更新:nil
从=
检查中删除,因为代码也可以正常工作。
Leaky Nun保存了84个字节
mathmandan保存了2个字节
def s(n):
a=[s(j)for j in range(1,n)];i=1
while(i in a)|any((i+n)%j<1for j in range(2,i+n)):i+=1
return i
定义一个函数s(n),该函数以数字作为输入并返回A083569(n)。
p=lambda n:any(n%i<1for i in range(2,n))
素数检查。
while(i in a)|any(...