给定非负整数输出欧拉数(OEIS A122045)。
所有奇数索引的欧拉数均为可以使用以下公式计算偶数索引的欧拉数(表示虚数单位):
规则
- 将是一个非负整数,因此欧拉数在您的语言可表示的整数范围内。
测试用例
0 -> 1
1 -> 0
2 -> -1
3 -> 0
6 -> -61
10 -> -50521
20 -> 370371188237525
给定非负整数输出欧拉数(OEIS A122045)。
所有奇数索引的欧拉数均为可以使用以下公式计算偶数索引的欧拉数(表示虚数单位):
0 -> 1
1 -> 0
2 -> -1
3 -> 0
6 -> -61
10 -> -50521
20 -> 370371188237525
Answers:
EulerE
-咳嗽-
GoatImageQ
被低估
{(->*@E {1-sum @E».&{$_*2**(@E-1-$++)*[*](@E-$++^..@E)/[*] 1..$++}}...*)[$_]}
从这里使用迭代公式:
常规结构是一个lambda,在该lambda中,将生成一个无限序列,该表达式将被反复调用并在变量中获取序列的所有先前值@E
,然后使用lambda参数为该序列建立索引:
{ ( -> *@E { } ... * )[$_] }
该序列的每个步骤所调用的表达式为:
1 - sum @E».&{ # 1 - ∑
$_ # Eₙ
* 2**(@E - 1 - $++) # 2ⁿ⁻ˡ⁻ᵏ
* [*](@E - $++ ^.. @E) # (n-k-1)·...·(n-1)·n
/ [*] 1..$++ # 1·2·...·k
}
F=(a,b=a)=>a?(b+~a)*F(--a,b-2)+F(a,b)*++b:+!b
where is defined as below. Specifically, the recurrence formula for is
F=(a,b=a)=>a?-F(--a,b)*++b+F(a,b-=3)*(a-b):+!b
Surprised to find no JavaScript answer yet, so I'll have a try.
The code consists of only basic mathematics, but the mathematics behind the code requires calculus. The recursion formula is derived from the expansion of the derivatives of of different orders.
Here I'll use some convenient notation. Let and . Then we have
Since and , we can deduce that
Let and , we can rewrite the relation above as
That is, contributes to both and . As a result, we can write in terms of and :
with initial condition and where .
The related part of the code a?-F(--a,b)*++b+F(a,b-=3)*(a-b):+!b
is exactly calculating using the above recurrence formula. Here's the breakdown:
-F(--a,b) // -F(n-1, i) [ a = n-1, b = i ]
*++b // *(i+1) [ a = n-1, b = i+1 ]
+F(a,b-=3) // +F(n-1, i-2) [ a = n-1, b = i-2 ]
*(a-b) // *((n-1)-(i-2)) [ a = n-1, b = i-2 ]
// which is equivalent to *(n-i+1)
Since and , equals the coefficient of in the expansion of , which is .
For branches that can never be reached, the recurrences always end at 0, so where or is odd. The latter one, particularly, implies that for all odd s. For even s strictly larger than , the recurrence may eventually allow to happen at some point, but before that step it must reach a point where , and the recurrence formula shows that the value must be 0 at that point (since the first term is multiplied by , and the second term is farther from the "triangle" of ). As a result, where . This completes the proof of the validity of the algorithm.
The code can be modified to calculate three more related sequences:
Tangent Numbers (46 bytes)
F=(a,b=a)=>a?F(--a,b)*++b+F(a,b-=3)*(a-b):+!~b
Secant Numbers (45 bytes)
F=(a,b=a)=>a?F(--a,b)*++b+F(a,b-=3)*(a-b):+!b
Euler Zigzag Numbers (48 bytes)
F=(a,b=a)=>a?F(--a,b)*++b+F(a,b-=3)*(a-b):!b+!~b
This just supports a hardcoded set of the first 16 Euler numbers (i.e. E0 to E15). Anything beyond that wouldn't fit in a 32-bit Befunge value anyway.
&:2%v
v@.0_2/:
_1.@v:-1
v:-1_1-.@
_5.@v:-1
v:-1_"="-.@
_"}$#"*+.@v:-1
8**-.@v:-1_"'PO"
"0h;"3_"A+y^"9*+**.@.-*8+*:*
I've also done a full implementation of the formula provided in the challenge, but it's nearly twice the size, and it's still limited to the first 16 values on TIO, even though that's a 64-bit interpreter.
<v0p00+1&
v>1:>10p\00:>20p\>010g20g2*-00g1>-:30pv>\:
_$12 0g2%2*-*10g20g110g20g-240pv^1g03:_^*
>-#1:_!>\#<:#*_$40g:1-40p!#v_*\>0\0
@.$_^#`g00:<|!`g01::+1\+*/\<
+4%1-*/+\2+^>$$10g::2>\#<1#*-#2:#\_$*\1
The problem with this algorithm is that the intermediate values in the series overflow much sooner than the total does. On a 32-bit interpreter it can only handle the first 10 values (i.e. E0 to E9). Interpreters that use bignums should do much better though - PyFunge and Befungee could both handle at least up to E30.
from sympy import *
t=n+2
print n,re(Add(*map(lambda (k,j):I**(k-2*j-1)*(k-2*j)**(n+1)*binomial(k,j)/(k*2**k),[(c/t+1,c%t) for c in range(0,t**2-t)])))
This is very suboptimal but it's trying to use basic sympy functions and avoid floating point. Thanks @Mego for setting me straight on the original formula listed above. I tried to use something like @xnor's "combine two loops" from Tips for golfing in Python
import*
(remove the space in between) to save a byte. Also, you need to take the number as an input somehow (snippets which assume the input to be in a variable are not allowed).
{1a{_W%_,,.*0+(+W%\_,,:~.*.+}@*W=}
Online demo which prints E(0) to E(19). This is an anonymous block (function).
The implementation borrows Shieru Akasoto's recurrence and rewrites it in a more CJam friendly style, manipulating entire rows at a time.
{ e# Define a block
1a e# Start with row 0: [1]
{ e# Loop...
_W% e# Take a copy and reverse it
_,,.* e# Multiply each element by its position
0+(+ e# Pop the 0 from the start and add two 0s to the end
W% e# Reverse again, giving [0 0 (i-1)a_0 (i-2)a_1 ... a_{i-2}]
\ e# Go back to the other copy
_,,:~.* e# Multiply each element by -1 ... -i
.+ e# Add the two arrays
} e#
@* e# Bring the input to the top to control the loop count
W= e# Take the last element
}
Without using any special functions:
e@0=1;e@n_:=-n!Sum[e[n-k]/k!/(n-k)!,{k,2,n,2}]
euler
for OEIS A122045; this is 57 bytes
g(n:NNI):INT==factorial(n)*coefficient(taylor(sech(x)),n)
test code and results
(102) -> [[i,g(i)] for i in [0,1,2,3,6,10,20]]
(102)
[[0,1],[1,0],[2,- 1],[3,0],[6,- 61],[10,- 50521],[20,370371188237525]]
(103) -> [[i,euler(i)] for i in [0,1,2,3,6,10,20]]
(103)
[[0,1],[1,0],[2,- 1],[3,0],[6,- 61],[10,- 50521],[20,370371188237525]]
E←{0≥w←⍵:1⋄1-+/{(⍵!w)×(2*w-1+⍵)×E⍵}¨¯1+⍳⍵}
按照“ smls”中显示的公式进行测试:
E 0
1
E 1
0
E 3
0
E 6
¯61
E 10
¯50521
最后一种情况作为结果返回一个大有理数,因为我输入20x(大有理数20/1)而不是20,因为我认为20.0浮动64位...
E 20x
370371188237525
如果一个很快返回0,会更快一些,但是会更长一些(50个字符):
E←{0≥w←⍵:1⋄0≠2∣w:0⋄1-+/{(⍵!w)×(2*w-1+⍵)×E⍵}¨¯1+⍳⍵}
E 30x
¯441543893249023104553682821
如果使用有问题的定义,将会更快(并且会更长一些75个字符):
f←{0≥⍵:1⋄0≠2∣⍵:0⋄0J1×+/{+/⍵{⍺÷⍨(0J2*-⍺)×(⍵!⍺)×(¯1*⍵)×(⍺-2×⍵)*n}¨0..⍵}¨⍳n←1+⍵}
f 0
1
f 1
0
f 3
0
f 6
¯61J0
f 10
¯50521J¯8.890242766E¯9
f 10x
¯50521J0
f 20x
370371188237525J0
f 30x
¯441543893249023104553682821J0
f 40x
14851150718114980017877156781405826684425J0
f 400x
290652112822334583927483864434329346014178100708615375725038705263971249271772421890927613982905400870578615922728
107805634246727371465484012302031163270328101126797841939707163099497536820702479746686714267778811263343861
344990648676537202541289333151841575657340742634189439612727396128265918519683720901279100496205972446809988
880945212776281115581267184426274778988681851866851641727953206090552901049158520028722201942987653512716826
524150450130141785716436856286094614730637618087804268356432570627536028770886829651448516666994497921751407
121752827492669601130599340120509192817404674513170334607613808215971646794552204048850269569900253391449524
735072587185797183507854751762384660697046224773187826603393443429017928197076520780169871299768968112010396
81980247383801787585348828625J0
上面的结果是一个只有实数的复数。
-i/2
,-i
在相加时产生。将其乘以i
求和的外部,即可得到1
。