http://projecteuler.net/index.php?section=problems&id=59
3分割して、それぞれ最頻の数を選んで、それはスペースだとみて、キーを作る。
import Data.List split [c] = [[c]] split (c:cs) | c == ',' = []:(split cs) | otherwise = ([c] ++ s2):cs2 where (s2:cs2) = split cs divide a m k | k == m = [] divide a m k | otherwise = (f b):(divide a m (k + 1)) where b = zip [0..] a f x = map (\(_,n) -> n) (filter (\(n,_) -> mod n m == k) x) count [] d = 0 count (x:xs) d = (if x == d then 1 else 0) + (count xs d) decrypt a = sum(concat (map (\(k,c) -> map (\e -> xor k e) c) (zip keys b))) where b = (divide (map read (split a)) 3 0) freq 128 a = [] freq d a = (d, count a d):(freq (d + 1) a) max_freq b = foldr (\x y -> if snd x >= snd y then x else y) (0, 0) b keys = map ((xor 32) . fst . max_freq . (freq 0)) b bin n 0 = [] bin n k = (mod n 2):(bin (div n 2) (k - 1)) xor n m = foldr (\x y -> x + 2 * y) 0 [ mod (a + b) 2 | (a, b) <- zip (bin n 8) (bin m 8) ] main = do cs <- readFile "cipher1.txt" print (decrypt cs)