dreiNplusEins :: Integer -> [Integer]
dreiNplusEins n = if n == 1 then [1] else if n `mod` 2 == 0 then
[n] ++ dreiNplusEins (n `div` 2)
else
[n] ++ dreiNplusEins (n * 3 + 1)
maxZyklus :: UntereGrenze -> ObereGrenze -> (UntereGrenze,ObereGrenze,MaxZyklaenge)
maxZyklus m n = if m > n then (m,n,0) else if m == n then
(m,n,length(dreiNplusEins m))
else
(m,n,0)
type UntereGrenze = Integer
type ObereGrenze = Integer
type MaxZykLaenge = Integer
这是我的程序,这给出了错误,因为不在范围内:类型构造函数或类`MaxZyklaenge'我该如何修复它?
答案 0 :(得分:6)
类型名称中有拼写错误:
在maxZyklus
的类型签名中,您编写MaxZyklaenge
(小写l),但在类型定义中,您编写MayZykLaenge
(大写L)。
答案 1 :(得分:4)
即使你修正了拼写错误,你仍然会收到错误,因为length
会返回Int
,而你需要Integer
。以下是解决此问题的一种方法(我还重写了使用警卫的代码):
import Data.List (genericLength)
dreiNplusEins :: Integer -> [Integer]
dreiNplusEins 1 = [1]
dreiNplusEins n
| n `mod` 2 == 0 = n : dreiNplusEins (n `div` 2)
| otherwise = n : dreiNplusEins (n * 3 + 1)
maxZyklus :: UntereGrenze -> ObereGrenze -> (UntereGrenze, ObereGrenze, MaxZyklaenge)
maxZyklus m n
| m == n = (m, n, genericLength $ dreiNplusEins m)
| otherwise = (m, n, 0)
type UntereGrenze = Integer
type ObereGrenze = Integer
type MaxZyklaenge = Integer
如果您不想要额外的fromIntegral . length
,也可以使用import
,但我个人认为genericLength
更清晰一点。
另外,如果你感兴趣的话,这是编写第一个函数的一种可以说是更好的方法:
dreiNplusEins :: Integer -> [Integer]
dreiNplusEins = (++[1]) . takeWhile (/=1) . iterate f
where
f n | even n = n `div` 2
| otherwise = n * 3 + 1
这只是说“迭代地应用f
直到你点击1
,然后在最后点1
。”
要查找产生最长链的给定范围内的数字,可以使用以下函数:
longestBetween :: (Enum a, Integral b) => (a -> [b]) -> (a, a) -> (a, b)
longestBetween f (m, n)
= maximumBy (comparing snd)
. zip [m..n] $ map (genericLength . f) [m..n]
第一个参数是创建列表的函数,第二个参数是范围。返回值是一个元组,包含范围中的所需数字和列表的长度。请注意,我们需要这些额外的导入:
import Data.List (genericLength, maximumBy)
import Data.Ord (comparing)
我们可以测试如下:
*Main> longestBetween dreiNplusEins (100, 1000)
(871,179)
实现您在评论中指定的maxZyklus
函数只需要进行一些小的更改:
maxZyklus m n = (m, n, maximum $ map (genericLength . dreiNplusEins) [m..n])
maxZyklus 11 22
提供了所需的(11, 22, 21)
。
答案 2 :(得分:1)
Haskell区分大小写。
在maxZyklus
的类型签名中:
... ,MaxZyklaenge)
-- # ^
但你有:
type MaxZykLaenge = Integer
-- # ^
答案 3 :(得分:0)
它被定义为MaxZykLaenge
(注意“L”),而你将类型写为“MaxZyklaenge”。 Haskell区分大小写。