我正在尝试解决项目的问题。我想以整数螺旋形式创建元素列表。
我有这个功能:
next_four_numbers last size = map (\p -> last + p*(size-1)) [1,2,3,4]
我当然还有其他方法来生成它,但最后我希望有无限的序列:
diagonal_spiral_numbers = [1,3,5,7,9,13,17,21,25,31,37,43,49 ...]
我怎样才能使用“next_four_numbers”函数创建这个infinte序列?当然我希望它能够有效地映射这个(我希望能够做到这一点):
take 20000 ( filter is_prime diagonal_spiral_numbers )
谢谢,
ps:当然我正在学习haskell,它可能比我想象的要容易。
答案 0 :(得分:4)
如果您有一个基于前一个生成下一个状态的函数,则可以使用iterate
函数创建整个列表。在这种情况下,状态由四个数字和大小组成。调用iterate后,我调用map fst
来删除size
值,并调用concat
来连接所有列表。
nextState (prev,size) = (next_four_numbers (last prev) size, size+2)
allNums = concat $ map fst $ iterate nextState ([1],3)
答案 1 :(得分:1)
你可以这样做:
diagonal_spiral_numbers =
let helper l s =
let next_four_numbers last size = map (\p -> last + p*(size-1)) [1,2,3,4]
(a:b:c:d:[]) = next_four_numbers l s
in a:b:c:d : helper d (s+2)
in 1 : helper 1 3
这里输出:
take 20 diagonal_spiral_numbers
[1,3,5,7,9,13,17,21,25,31,37,43,49,57,65,73,81,91,101,111]
但是我想知道你为什么需要使用next_four_numbers
函数:结果列表可以用更简单的方式生成(我会说整体更好的)。
答案 2 :(得分:0)
当然可以这样做,生成一个列表列表然后flattening它(查看concatMap函数),但通常的方法是让你的帮助函数采用额外的“尾”参数,然后返回a:b:c:d:tail。
另一种方法是使用zipWith3。
答案 3 :(得分:0)
请注意,您的last
和size
参数的格式始终分别为(2x+1)^2
和2x+3
(x
中的0,1,2,3,...
)
您只需要使用这些参数调用next_four_numbers一次。这可以通过列表理解来实现:
diagonals = [next_four_numbers ((2*x+1)*(2*x+1)) (2*x+3) | x <- [0..]]
或者使用地图(如果你对此感觉更舒服):
diagonals = map (\x -> next_four_numbers ((2*x+1)*(2*x+1)) (2*x+3)) [0..]
然后,这只是扁平化列表并在前面加1:
actual_diagonals = 1:concat diagonals
main = print (take 20 actual_diagonals)
这可能会被清理一下,但我会把它留给你;)
顺便说一下,[0..]
只是无限列表0,1,2,3,...