LoginSignup
2
2

More than 5 years have passed since last update.

Project Eulerをhaskellで練習していく日記: Problem 13

Posted at

問題

以下の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
2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2