Project Euler 22,23

Problem 22

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


ファイルからテキストを読むにはreadFileを使う。
文字をアスキーコードにするにはChar.ordを使う。
switch文のようなcase式がある。


import Data.List
import Char

split_core buff [] = []
split_core [] (c:cs) = case c of
'\"' -> split_core [] cs
',' -> split_core [] cs
otherwise -> split_core [c] cs
split_core buff (c:cs) = case c of
'\"' -> [buff] ++ (split_core [] cs)
otherwise -> split_core (buff ++ [c]) cs
split s = split_core [] s

sum_char s = sum(map (\c -> (Char.ord c) - (Char.ord 'A') + 1) s)

main = do
cs <- readFile "names.txt"
print(sum([ (sum_char s) * n | (s, n) <- (zip (sort (split cs)) [1..])]))

Problem 23

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


まず過剰数のリストを求める。
そして、配列を用意し、過剰数の和に対応する要素をTrueにする。


import Data.Array

divs_half n = filter (\k -> (mod n k) == 0)
(takeWhile (\k -> k * k <= n) [2..])
d n = (sum (a ++ (map (div n) (filter (\k -> k * k < n) a)))) + 1
where a = divs_half n

update [] b = b
update (n:ns) b = update ns (b // [ (n + p, True) | p <- (n:ns), n + p <= m ])

m = 28123
a = filter (\n -> (d n) > n) [1..m]
b = array (1, m) [ (k, False) | k <- [1..m] ]
c = update a b
main = print(sum(filter (\k -> not (c!k)) [1..m]))