問題
以下の100個の50桁の数の和の最初の10桁を求めよ。
37107287533902102798797998220837590246510135740250
46376937677490009712648124896970078050417018260538
74324986199524741059474233309513058123726617309629
91942213363574161572522430563301811072406154908250
23067588207539346171171980310421047513778063246676
89261670696623633820136378418383684178734361726757
28112879812849979408065481931592621691275889832738
44274228917432520321923589422876796487670272189318
47451445736001306439091167216856844588711603153276
70386486105843025439939619828917593665686757934951
以下略
回答
calc2 :: [String] -> Integer
calc2 xs = sum $ map read xs
readnumfile = do
contents <- getContents
return $ words contents
main = do
numbers <- readnumfile
print $ take 10 $ show $ calc2 numbers
感想
Integer型を使えば、どんな大きい数も計算できるので、とりあえずは上記でいいのでしょうけど。
今回、入力は標準入力から読むようにしました。
無理矢理dataの練習をしたくて、あえて筆算を行うバージョンを作ったのが以下。
data Keta a = Keta { num :: a, afure :: a} deriving (Show)
add :: (Integral a) => (Keta a) -> (Keta a) -> (Keta a)
add (Keta {num=a, afure=b}) (Keta {num=c, afure=d}) = Keta {num=(a+c) `mod` 10,afure=b+d+((a+c) `div` 10)}
kanyaku :: (Integral a) => [Keta a] -> [Keta a]
kanyaku [] = []
kanyaku (x:[]) = if afure s>0 then Keta {num=num s,afure=0}: (kanyaku [Keta {num=afure s,afure=0}])
else s:[]
where n = num x
s = Keta{num=n `mod` 10, afure=afure x+(n `div` 10)}
kanyaku (x1:x2:xs) = (Keta {num=n `mod` 10, afure=0}): (kanyaku ((Keta{num=(num x2)+(afure x1)+(n `div` 10), afure=afure x2}):xs))
where n = num x1
keta n = Keta {num=n, afure=0}
numlist :: String -> [Keta Int]
numlist str = reverse $ map (keta . read . (:[])) str
addketas xs [] = xs
addketas [] ys = ys
addketas (x:xs) (y:ys) = (x `add` y): (addketas xs ys)
calc xs = foldl addketas [] xs
ketas2num = concat . map (show.num) . reverse . kanyaku
readnumfile = do
contents <- getContents
return $ words contents
main = do
numbers <- readnumfile
print $ take 10 $ ketas2num $ calc $ map numlist numbers