http://projecteuler.net/index.php?section=problems&id=79
ものすごくいい加減な解法。数字が右にあるか左にあるか、各ペアで調べる。50個のリストでそれがすべて分かるので、順番が付けられる。
import Data.List import qualified Data.Map as M import qualified Data.Set as S digits :: Int -> [Int] digits 0 = [] digits n = (digits (div n 10)) ++ [mod n 10] to_number a = foldl1 (\x y -> x * 10 + y) a used_digits a = S.toList (f S.empty a) where f s [] = s f s (d:ds) = f (S.insert d s) ds solve a = to_number (sortBy cmp ds) where ds = used_digits (concat a) ds2 = [ (x, y) | x <- ds, y <- ds, x /= y ] m = update a (M.fromList [ (xy, 0) | xy <- ds2 ]) update [] m = m update (dd:a) m = update2 (g dd) (update a m) update2 [] m = m update2 ((d,mode):dd) m = M.insert d mode (update2 dd m) g [d1, d2, d3] = [ ((d1,d2),1),((d1,d3),1),((d2,d3),1), ((d2,d1),2),((d3,d1),2),((d3,d2),1) ] f d = sum [ m M.! (d,d1) | d1 <- ds, d1 /= d ] cmp d1 d2 = compare (f d1) (f d2) main = do cs <- readFile "keylog.txt" print (solve (map (digits . read) (lines cs)))