无限列表的模式是从左上角a1开始,然后依次为a2到b1、a3到c1
a1 a2 a3 a4
b1 b2 b3 b4
c1 c2 c3 c4
d1 d2 d3 d4
即a1,a2 b1,a3 b2 c1,a4 b3 c2 d1
逗号分隔的字母为
a ab abc abcd
和数字
1 21 321 4321
无限列表输出应首先以a1对角线增长,然后添加2个对角线,然后添加3个对角线,依此类推。
上述任何一个单个字母或数字都必须向反方向发展。
diag xs ys = [(a,b)| (m,n) <- zip (inits xs) (inits ys), (a,b) <- zip m $ reverse n ]
对于每个 (m,n)
对,我更喜欢一次性反转所有元素,而不是重复单个操作。我认为只有通过连续反转列表才能实现无限列表的反转。
rsl = tail.scanl (flip (:)) []
take 5 $ rsl [1..]
[[1],[2,1],[3,2,1],[4,3,2,1],[5,4,3,2,1]]
然后逐个处理每个列表。 zip
在每次迭代中限制非反转列表。
plr xs ys = [ (a,b) | ls <- rsl xs, (a,b) <- zip ls ys ]
sort.take 10.plr ['a'..] $ [1..]
[('a',1),('a',2),('a',3),('a',4),('b',1),('b',2),('b',3),('c',1),('c',2),('d',1)]
sort
,因为按对角线取值意味着它们不像上面的第一个线性列表那样有序。 sort
是从 Data.List 导入的。
顺便说一下,因为这是沿着对角线遍历,所以三角形数也会出现。我在上面使用了 take 10
,三角形数是:
take 11 [sum ls | ls <- rsl [1..]]
[1,3,6,10,15,21,28,36,45,55,66]
n
多大? - dave44203^n
已经超出了RAM的大小。 - Vincent Beffara