小町算っぽいやつ
30分プログラム、その106。小町算をやろうとして、挫折したやつ。
元ネタはたぶん、LL魂。
ダメな理由。
- 空白に対応していない
- 括弧を使ってしまっている
使い方
*Main> mapM_ (putStrLn.show) $take 3 ans (1.0+(2.0+(3.0+(4.0+(5.0-(6.0+(7.0-(8.0+(9.0*10.0))))))))) (1.0+(2.0+(3.0+(4.0-(5.0-(6.0+(7.0-(8.0-(9.0*10.0))))))))) (1.0+(2.0+(3.0*(4.0+(5.0/(6.0/(7.0+(8.0+(9.0+10.0)))))))))
ソースコード
import Data.List import Control.Monad.List data Exp = Exp `Add` Exp | Exp `Sub` Exp | Exp `Mul` Exp | Exp `Div` Exp | Number Float instance Show Exp where show (Number a) = show a show (a `Add` b) = "("++(show a)++"+"++(show b)++")" show (a `Sub` b) = "("++(show a)++"-"++(show b)++")" show (a `Mul` b) = "("++(show a)++"*"++(show b)++")" show (a `Div` b) = "("++(show a)++"/"++(show b)++")" -- なんとなくfoldl1っぽい makeExp :: [Float]->[Exp] makeExp [x] = [Number x] makeExp (x:xs) = do op <- [Add,Sub,Mul,Div] xs' <- makeExp xs return $ (Number x) `op` xs' eval :: Exp -> Float eval (Number x) = x eval (a `Add` b) = (eval a) + (eval b) eval (a `Sub` b) = (eval a) - (eval b) eval (a `Mul` b) = (eval a) * (eval b) eval (a `Div` b) = (eval a) / (eval b) komachi target xs = do exp <- makeExp xs guard $ eval exp == target return exp ans = komachi 100 [1..10]