找到"差距"在一个数字列表中

时间:2017-10-11 00:53:02

标签: haskell

我在浏览列表时遇到了麻烦。我制作了这个代码,它给了我一个数字列表,这些数字均匀地除以它们的数字之和。例如,考虑数字123:123/6 = 20.5,因此它不在列表中。另一只手280将在列表中,因为280/10 = 28。

let inaHelper x = (floor(x)`mod`10)+ (floor(x/10)`mod`10)+(floor(x/100)`mod`10)

let ina = [x | x <- [1..999] , x `mod` (inaHelper x) == 0  ]  

[1,2,3,4,5,6,7,8,9,10,12,18,20,21,24,27,30,36,40,42,45,48,50,54,60,63,70,72,80,81,84,90,100,102,108,110,111,112,114,117,120,126,132,133,135,140,144,150,152,153,156,162,171,180,190,192,195,198,200,201,204,207,209,210,216,220,222,224,225,228,230,234,240,243,247,252,261,264,266,270,280,285,288,300,306,308,312,315,320,322,324,330,333,336,342,351,360,364,370,372,375,378,392,396,399,400,402,405,407,408,410,414,420,423,432,440,441,444,448,450,460,465,468,476,480,481,486,500,504,506,510,511,512,513,516,518,522,531,540,550,552,555,558,576,588,592,594,600,603,605,612,621,624,629,630,640,644,645,648,660,666,684,690,700,702,704,711,715,720,730,732,735,736,738,756,770,774,777,780,782,792,800,801,803,804,810,820,825,828,832,840,846,864,870,874,880,882,888,900,902,910,912,915,918,935,936,954,960,966,972,990,999]

但我现在的问题是:从上面的列表中我只想要那些没有&#34;邻居&#34;在5个单位的差距内。例如,数字300将在新列表中,因为它的邻居(288和306)不在5个单位间隙内。

我想出了这段代码:

let rare = [ x | x <- [ina]  , ((x-5) >= [ina-1]) && ((x+5) <= [ina+1])    ]

我是初学者,有人可以帮忙吗?

1 个答案:

答案 0 :(得分:2)

一种简单但不是非常有效的方法是创建一个辅助函数来检查某个范围内是否存在列表元素:

hasElemInRange :: (Int,Int) -> [Int] -> Bool
hasElemInRange (lo, hi) xs = -- left as exercise

(提示:您可以使用any功能)

然后您可以将其包含在列表理解中:

let rare = [ x | x <- ina, hasElemInRange (x-5,x+5) ina ]

你可能会考虑的另一个成语是用自己的尾巴压缩列表。所以你可以这样做:

ghci> let xs = [1,2,3,4,5,6,7]
ghci> zip3 xs (tail xs) (tail (tail xs))
[(1,2,3),(2,3,4),(3,4,5),(4,5,6),(5,6,7)]

这将为您提供列表中的每个元素及其&#34; context&#34;,前后的元素。也许你可以弄清楚如何将它用于你需要的东西。