我需要计算一个名为happy的函数的递归调用。我得到一个提示,我可以使用辅助功能来做到这一点。我只是想不通,我应该如何实现它。递归达到1000次调用后应该停止。
digits :: Integer -> [Integer]
digits x
| x < 1 = []
| x == 1 = [1]
| otherwise = x `mod` 10 : digits (x `div` 10)
squareSum :: [Integer] -> Integer
squareSum (x:xs) = sum (map (^2) (x:xs))
happy :: Integer -> Bool
happy x
| x == 1 = True
| otherwise = (happy . squareSum . digits) x
happyNumbers :: [Integer]
happyNumbers = filter happy [1..500]
digits
函数获取一个整数,并创建一个包含数字的列表。
squareSum
函数对这些数字进行平方运算,并对它们进行汇总。
happy
是它反复调用自身的函数,但是当它达到1000个调用时,我需要停止它。
答案 0 :(得分:3)
据我所知,快乐数字是happy
生成的序列收敛为1的那些,因此您可以返回True
,而不快乐则是那些顺序永远持续下去。您想返回False
,但是现在您的代码只是在不满意的数字上循环。 (例如,happy 1
返回True
,但happy 2
挂起。)
执行此操作的通常方法是引入一个用作倒数计时的新参数。得到的提示是要引入辅助功能happy'
,这样您就不必更改happy
的类型签名。尝试定义:
happy :: Integer -> Bool
happy x = happy' 1000 x
happy' :: Integer -> Integer -> Bool
happy' countDown x
| x == 1 = True
| otherwise = (happy' (countDown - 1) . squareSum . digits) x
到目前为止,此“解决方案”仍将永远运行,但是现在您有了一个countDown
参数!您应该能够添加一个新的受保护的大小写,以检查countDown
是否已过期以返回False
。