Project Euler (Problem ID 11..15)
ID 11から15まで。
関数primes、factorとprimeFactorsは、ID 3の使い回し。
ID 11のコードをうまく書けず、汚くなってしまった…
ID 12では、素因数分解してから、また積をとっているのが良くない気がする。
素因数分解したときの指数だけ見れば良いのかな?
ID 11..15
import List primes = [2] ++ sieve [3,5..] where sieve (p:ns) = [p] ++ (sieve $ filter (\n -> rem n p /= 0) ns) factor 1 _ = [] factor m (n:ns) | rem m n == 0 = (n:factor (quot m n) (n:ns)) | otherwise = factor m ns primeFactors n = factor n primes rtail n l | n == 0 = head l | otherwise = rtail (n - 1) $ tail l prog011 = last $ sort $ ((prods prodH4) ++ (prods prodV4) ++ (prods prodDrd4) ++ (prods prodDru4)) where at c r = rtail r $ rtail c $ the20x20grid prodH4 c r = product $ map (at c) $ [r..(r+3)] prodV4 c r = product $ map (\col -> at col r) $ [c..(c+3)] prodDrd4 c r = product $ map (\i -> at (c+i) (r+i)) $ [0..3] prodDru4 c r = product $ map (\i -> at (c+i) (r+3-i)) $ [0..3] prods p = [p c r | c <- [0..16], r <- [0..16]] combinations (x:xs) n | n == 0 = [[]] | n == length (x:xs) = [(x:xs)] | otherwise = [(x:cs) | cs <- combinations xs (n - 1)] ++ (combinations xs n) triangleNum n = sum $ [1..n] factors n | n == 1 = [1] | otherwise = uniq $ sort $ (++) [1] $ map product [cs | m <- [1..length ps], cs <- combinations ps m] where ps = primeFactors n prog012 = head $ dropWhile (\z -> snd z < 500) zipped where tNums = map triangleNum [1..] zipped = zip tNums (map (length . factors) tNums) prog013 = take 10 $ show theSum where theSum = 37107287533902102798797998220837590246510135740250 + 46376937677490009712648124896970078050417018260538 + -- 中略 20849603980134001723930671666823555245252804609722 + 53503534226472524250874054075591789781264330331690 collatzs n | n == 1 = [1] | otherwise = n:(collatzs (collatz n)) where collatz n | even n = div n 2 | otherwise = (3 * n) + 1 prog014 = last $ sort $ zip (map (length . collatzs) sNums) sNums where sNums = [1..(1000 * 1000 - 1)] prog015 = div (product [21..40]) (product [1..20]) main = putStrLn $ show $ prog015