嗨,我是 Haskell 的新手,我遇到了一个有趣的问题,但我不确定如何解决它。我将仅向您展示问题的两个部分作为示例。
问题是我们要输入一个 13 到 15 位数字之间的数字。然后从该数字中删除最后一个数字。例如 19283828382133 应该输出完全相同的数字,只是没有最后的 3,1928382838213。
然后这些数字中的每个奇数(不是数字)都会加倍。所以你会得到 2,9,4,8,6 等
到目前为止,这是我的代码。正如您从代码中看到的,我已经能够单独完成这两部分(工作),但我不确定如何将它们添加在一起。
lastdigit :: Integer -> Integer -- This Function removes the last number
lastdigit x = x`div`10
doubleOdd (x:xs) = (2*x):(doubleEven xs) -- This function doubles every odd digit not number.
doubleOdd [] = []
doubleEven (x:xs) = x:(doubleOdd xs)
doubleEven [] = []
因此,为了进一步解释我正在尝试构建的程序,首先要完成输入 13 到 15 位数字的步骤。然后它将首先删除最后一个数字,然后自动进入下一步将每个奇数(不是数字)加倍。谢谢
缺失的部分是一种将整数分解成其数字并从那里重新构建它的方法。这很容易:
digits:: Int -> [Int]
digits = map (`mod` 10) . takeWhile (/= 0) . iterate (`div` 10)
undigits :: [Int] -> Int
undigits = foldr f 0 where f i r = 10 * r + i
然后看起来您需要以两种不同的方式对这些数字进行后处理,但前提是它们与谓词匹配。让我们为此构建一个组合器:
when :: (a -> Bool) -> (a -> a) -> a -> a
when p f a = if p a then f a else a
第一种情况出现在您想在奇数位置(从左到右)上双位数。再次是微不足道的,digits
通过增加十的幂来分解数字会带来一些不便。让我们用每个数字的位置作为前缀:
prefix :: [Int] -> [(Int, Int)]
prefix is = let n = length is in zip [n, n-1..1] is
doubleOdd
现在可以表示为
doubleodd :: [Int] -> [Int]
doubleodd = map (snd . when (odd . fst) (id *** double)) . prefix
您在评论中提到,当双数溢出时,必须将其数字相加。这是我所指的第二种情况,它本身也很简单:
double :: Int -> Int
double = when (>= 10) (sum . digits) . (* 2)
这是你的最终程序:
program = undigits . doubleodd . tail . digits
...假设“13 到 15 位数字之间”部分是单独验证的。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句