5位数字黑圈
【题目】不同于4位数字,如果是一个5位数,像【问题19】那样运算,最终不会落入一个数字黑洞(0除外),而是在一组数字中不断地循环兜圈子。可以姑且称之为:数字黑圈吧。
请你计算一下,所有的5位数字,一共可能落入多少个数字黑圈。
与【问题19】相比,需要增加处理的是:如何判断一个数字已经落入黑圈。
我们可以在数字链中查找是否已经出现过这个数字,如果是,那必然形成黑圈。而且,我们可以注意到,其实黑洞只是黑圈的一种特殊形式(循环长度为1的黑圈)。
上代码:
----- 5位数数字黑圈
import Data.List (sort, elemIndex)
trans :: Int -> Int
trans n = read bigN - read smallN
where
digiN = take 5 . (++"00000") . show $ n
smallN = sort digiN
bigN = reverse smallN
chain :: Int -> [Int]
chain n = f n []
where
f m acc = case m `elemIndex` acc of
Just x -> take (x+1) acc
_ -> f (trans m) (m:acc)
allChain :: [[Int]]
allChain = map chain (foldr f [] [0..99999])
where
f x acc | king `elem` acc = acc
| otherwise = king:acc
where
king = minimum (chain x)
main = putStr $ unlines $ map show allChain
这个算法虽然能出结果,然而比较慢。原因是,对每个数字都要求一遍黑圈。而在形成黑圈的过程中,有许多数字都在重复计算。