haskellお勉強中

勉強がてらプロジェクトオイラーを10問まで解いてみた。
しかし、googleブログでソースコード表示って、どうすりゃ……

-------------------------------------------------------------

import Control.Monad (forM_, when)
import Control.Monad.ST
import Data.Array
import Data.Array.MArray
import Data.Array.ST
import Data.List

problem001 = sum [x | x <- [1..999], x `mod` 3 == 0 || x `mod` 5 == 0]

problem002 = sum $ takeWhile (< 4000000) $ filter even fib
  where fib = map fst $ iterate (\(x, y)->(y, x+y)) (1, 2)

problem003 = head $ primes 600851475143 [1] where 
  primes n (x:xs)
    | n <= x = nub $ filter (\x -> x > 1)(x:xs)
    | otherwise = primes (n `div` x) ((firstPrime (n `div` x) x):x:xs)
  firstPrime n 1 = firstPrime n 2
  firstPrime n x = head $ filter (\m -> n `mod` m == 0) [x..n]

problem004 = maximum [x*y | x<-[100..999], y<-[100..999],
            show (x*y) == reverse (show $ x*y)]

problem005 = foldl getLcm 1 [1..20] where
  getLcm x y = x*y `div`(euclidean x y)
  euclidean x y
    | x == y = x 
    | otherwise = euclidean (abs (x-y)) (min x y)

problem006 = sum [x*y*2 | x<-[1..100], y<-[x+1..100]]

problem007 = (sieve 2 [3,5..]) !! (10001 - 1)
  where sieve (x1:xs) = x1 : sieve [ x | x<-xs, (x ` rem` x1) /= 0]

problem008 = maximum $ map product (sliding 5 li) where
  li = map (\c -> (read [c])::Int) num
  sliding n xs
    | length xs < n = []
    | otherwise = (take n xs):(sliding n (tail xs))
  num = "7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450"

problem009 = [a*b*c | b<-[1..998], a<-[1..b+1], let c = 1000-a-b,
        a^2 + b^2 == c^2]

problem010 = sum $ primes 2000000 where
  sieve::ST s (STArray s Int Bool)->Int->Int->ST s (STArray s Int Bool)
  sieve arr n s = do
    a <- arr
    let findNext m = do
      c <- if (n > m) then readArray a m else return True
      if c then return m else (findNext (m+1))
    when (n >= s) $ forM_ [2*s, 3*s..n] $ \m -> writeArray a m False
    s2 <- findNext (s+1)
    if n >= s then sieve (return a) n s2 else return a 
  primes n = [fst x | x<-primBase, snd x] where
    primBase = assocs $ runSTArray $ sieve (newArray (2, n) True) n 2

-------------------------------------------------------------

色々と酷い感じなのは分かってます。
つか、STArrayの使い方がろくに分からず滅茶苦茶詰まった……ぅぅぅ
あと、少しはポイントフリースタイルで書こうとしようぜ、自分。

コメント

このブログの人気の投稿

BASARA の属性に関して思うこと

塔の上のラプンツェル 感想

コードギアスとはどんな物語だったのか?