Problem 12

http://projecteuler.net/index.php?section=problems&id=12

--Haskell, 20090104

import Sequence (trianglar)

enprimes :: Int -> Int -> [Int]
enprimes 1 _ = []
enprimes s n = let t = takeWhile ((==0).(s`mod`)) (iterate (*n) 1)
               in length t - 1 : enprimes (s`div`(last t)) (n+1)

main = print $ head [x | x<-trianglar, (product.map (+1).enprimes x) 2 > 500]

数列モジュールを使用.改善の余地あり.

Problem 14

http://projecteuler.net/index.php?section=problems&id=14

--Haskell (needs -fbang-patterns -package containers), 20090101

import Data.Map (findMax, fromList)

collatz :: Integer -> Integer
collatz !n | n==1      = 1
           | even n    = 1 + collatz (n`div`2)
           | otherwise = 2 + collatz ((n*3+1)`div`2)

main = print $ snd $ findMax $ fromList [(collatz (toInteger x), x) | x<-[1..999999]]

bang patternsを使わなければ,空間効率が悪すぎて終わらない.枝を刈ればもう少し速くなるだろう.

Problem 11

http://projecteuler.net/index.php?section=problems&id=11
traih.log様のSmartなコードを参考に.

--Haskell (Input data from STDIN), 20090101

import List (tails, transpose)

horizon, diagonal :: [[Int]] -> Int
horizon = maximum . map (maximum . map (product . take 4) . tails)
diagonal = horizon . transpose . zipWith drop [0..]

process :: [[Int]] -> Int
process = maximum . flip map [horizon, horizon.transpose, diagonal, diagonal.(map reverse)] . flip ($)

main = getContents >>= print . process . map (map read . words) . lines