どう書くは知ってる言語で解くのは楽しいけど、習い始めの言語はつらい。というわけで、mixiの課題丸投げあたりをチョイスすることが多い。
覆面算を解くというのがあったのでやってみた。XYZ + WXYZ + WXYZ + VWXYZ + VWXYZ = UVWXYZを満たす文字をそれぞれ求める。
題意からU=1は自明なんだけどあえて力技で。
-- XYZ + WXYZ + WXYZ + VWXYZ + VWXYZ = UVWXYZ
-- 4*Z + 4*10*Y + 4*100*X + 3*1000*W + 10000*V = 100000*U
check :: [Int] -> Bool
check (u:v:w:x:y:z:_) = 10000*v + 3000*w + 400*x + 40*y + 4*z == 100000*u
notDup :: [Int] -> Bool
notDup (x:xs)= notDup' x xs
where notDup' _ [] = True
notDup' x yy@(y:ys) | x `elem` yy = False
| otherwise = notDup' y ys
sol :: [[Int]]
sol = filter check $ filter notDup
[[u,v,w,x,y,z]|u <- [0..9], v <- [0..9], w <- [0..9], x <- [0..9], y <- [0..9], z <- [0..9]]
全通りの組み合わせを作ってから数字がダブっている組み合わせを除いた。
結局、組み合わせを最初から使えばいいので、0から9の数字の中から6つを選んで、それらの入れ替えをしながらチェックをするのもやってみた。
import List
check :: [Int] -> Bool
check (u:v:w:x:y:z:_) = 10000*v + 3000*w + 400*x + 40*y + 4*z == 100000*u
comb :: [Int] -> Int -> [[Int]]
comb _ 0 = [[]]
comb [] _ = []
comb (x:xs) n = map (x:) (comb xs (n-1)) ++ comb xs n
permutation [] = [[]]
permutation xs = concat [map (x:) $ permutation (delete x xs) | x <- xs]
sol = filter check $ concatMap permutation (comb [0..9] 6)
combとpermutationはProgramming:玉手箱:組合せを参考にした