http://projecteuler.net/index.php?section=problems&id=93
演算子の配列は、
operators = [ (+), (-), (*), (/) ]
けれど、実際の演算は、
op = (+) n = op 1 2 -- 3
と、前置にしなければならない。
0割りを回避するところで、演算子が(/)かどうかを直接判定する方法がわからなくて(型が指定されていないから?)、しかたなくインデックスにした。
import Data.List import Ratio import qualified Data.Set as S operators = [ (+), (-), (*), (/) ] consecutive_length a = f b where f [p,q] = if p + 1 == q then 2 else 1 f (p:q:ps) = if p + 1 == q then 1 + (f (q:ps)) else 1 b = S.toList s s :: S.Set Int s = S.fromList [ floor r | c <- permutations a, r <- g c, denominator r == 1 && r > 0 ] g :: [Ratio Int] -> [Ratio Int] g [d] = [d] g a = [ op p q | (ps,qs) <- h [] a, p <- g ps, q <- g qs, (k, op) <- zip [0..3] operators, q /= 0 || k /= 3 ] h ps [q] = [] h ps (q:qs) = (ps ++ [q],qs):(h (ps ++ [q]) qs) to_number a = floor (foldl (\x y -> x * 10 + y) 0 a) combinations a 0 = [[]] combinations a n = concat (map (\e -> map (e:) (combinations (filter (>e) a) (n - 1))) a) longer x y = if snd x >= snd y then x else y a = [ (to_number a, consecutive_length a) | a <- combinations [0..9] 4 ] main = print (fst (foldr longer (0,0) a))