我正在编写代码以查找第n个Ramanujan-Hardy编号。 Ramanujan-Hardy数字定义为Haskell性能优化
n = a^3 + b^3 = c^3 + d^3
表示n可以表示为两个立方体之和。
我写在Haskell下面的代码:
-- my own implementation for cube root. Expected time complexity is O(n^(1/3))
cube_root n = chelper 1 n
where
chelper i n = if i*i*i > n then (i-1) else chelper (i+1) n
-- It checks if the given number can be expressed as a^3 + b^3 = c^3 + d^3 (is Ramanujan-Hardy number?)
is_ram n = length [a| a<-[1..crn], b<-[(a+1)..crn], c<-[(a+1)..crn], d<-[(c+1)..crn], a*a*a + b*b*b == n && c*c*c + d*d*d == n] /= 0
where
crn = cube_root n
-- It finds nth Ramanujan number by iterating from 1 till the nth number is found. In recursion, if x is Ramanujan number, decrement n. else increment x. If x is 0, preceding number was desired Ramanujan number.
ram n = give_ram 1 n
where
give_ram x 0 = (x-1)
give_ram x n = if is_ram x then give_ram (x+1) (n-1) else give_ram (x+1) n
在我看来,时间复杂度检查,如果一个号码是拉马努金数为O(n ^(4/3))。
在ghci中运行此代码时,甚至需要花费时间才能找到第二个Ramanujan编号。
什么是可能的方法来优化此代码?
还可以在这里找到[data-ordlist]包(https://hackage.haskell.org/package/data-ordlist-0.4.7.0/docs/Data-List-Ordered.html)。 –
@PetrPudlák啊 - 'mergeAll'和/或'unionAll'可以在这里使用。 – ErikR