wvogel日記

自分用の技術備忘録が多めです.

train number(1)

とりあえず、動作までを確認したもの。

judge "1234"
のように、judge関数に、切符の値を渡してやればjudgeしてくれます。

あとは、演算子の組み合わせを全部網羅するようにしてやれば完成です。
んー、どうやろう。


oは、operatorのo,vは、valueのvです。

module Train where
import Text.Parsec
import Text.Parsec.String
import Control.Applicative hiding ((<|>),many)
import Data.List

opes = permutations ['+','-','*']

judge :: String -> IO()
judge xs = print .any (==10) $ fmap (run express) $ exprs xs

--式の集合
exprs :: String -> [String]
exprs = concat.map (mysort opes).permutations

--演算子と値から式を求める
mysort :: [String] -> String -> [String]
mysort [] _ = []
mysort (o:os) vs =mysort' (zip (o++"_") vs) : mysort os vs
  where
    mysort' [(_,v)] = [v]
    mysort' ((o,v):ovs) = v:o:mysort' ovs

run :: Parser Int ->String -> Int
run p input = case (parse p "" input) of
                Left err -> error"parse error..."
                Right  x -> x

num:: Parser Int
num = read<$>many1 digit

express :: Parser Int
express = do foldr ($)<$>factor<*> many (add<|>sub)
 where
  add = (+) <$>(char '+' >> factor)
  sub =flip (-) <$>(char '-' >> factor)

factor :: Parser Int
factor = do foldr ($)<$> num
               <*> (many $ (*) <$>(char '*'>> factor))