Concurrent Clean : send + more = money
http://d.hatena.ne.jp/syd_syd/20061018#p1
まずは、ナイーブに。
Start = [(s,e,n,d,m,o,r,y) \\ s <- [1..9], e <- [0..9] | not (isMember e [s]), n <- [0..9] | not (isMember n [s,e]), d <- [0..9] | not (isMember d [s,e,n]), m <- [1..9] | not (isMember m [s,e,n,d]), o <- [0..9] | not (isMember o [s,e,n,d,m]), r <- [0..9] | not (isMember r [s,e,n,d,m,o]), y <- [0..9] | not (isMember y [s,e,n,d,m,o,r]) && (s*1000+e*100+n*10+d) + (m*1000+o*100+r*10+e) == (m*10000+o*1000+n*100+e*10+y)]
順列を使って
perm :: [a] Int -> [[a]] | Eq a perm _ 0 = [[]] perm ls i | i > 0 = [[a:ar] \\ a <- ls, ar <- perm (filter (\b = a <> b) ls) (dec i)] Start = [(s,e,n,d,m,o,r,y) \\ [s,e,n,d,m,o,r,y] <- perm [0..9] 8 | s <> 0 && m <> 0 && (s*1000+e*100+n*10+d) + (m*1000+o*100+r*10+e) == (m*10000+o*1000+n*100+e*10+y)]
もうちょっと見やすく。
(base) infix 9 (base) ls b = base` 0 ls where base` n [] = n base` n [a:ar] = base` (n*b+a) ar perm :: [a] Int -> [[a]] | Eq a perm _ 0 = [[]] perm ls i | i > 0 = [[a:ar] \\ a <- ls, ar <- perm (filter (\b = a <> b) ls) (dec i)] Start = [(s,e,n,d,m,o,r,y) \\ [s,e,n,d,m,o,r,y] <- perm [0..9] 8 | s <> 0 && m <> 0 && [s,e,n,d] base 10 + [m,o,r,e] base 10 == [m,o,n,e,y] base 10]
あ、ここはfoldlでいいのか