Chinaunix首页 | 论坛 | 博客
  • 博客访问: 179809
  • 博文数量: 42
  • 博客积分: 2185
  • 博客等级: 大尉
  • 技术积分: 455
  • 用 户 组: 普通用户
  • 注册时间: 2009-06-11 21:32
文章分类

全部博文(42)

文章存档

2012年(5)

2011年(13)

2010年(6)

2009年(18)

我的朋友

分类:

2010-09-01 01:02:13

The following code mostly came from book ``Programming in haskell''.


-- countdown.hs

import Data.List
import System.Environment

data Op = Add | Sub | Mul | Div
                 
instance Show Op where
  show Add = "+"
  show Sub = "-"
  show Mul = "*"
  show Div = "/"
  
valid :: Op -> Int -> Int -> Bool

valid Add _ _ = True
valid Sub x y = x > y
valid Mul _ _ = True
valid Div x y = x `mod` y == 0

apply :: Op -> Int -> Int -> Int

apply Add x y = x + y
apply Sub x y = x - y
apply Mul x y = x * y
apply Div x y = x `div` y

data Expr = Val Int | App Op Expr Expr
                   
instance Show Expr where
  show (Val n) = show n
  show (App op l r) = "(" ++ (show l) ++ (show op) ++ (show r) ++ ")"
  
values :: Expr -> [Int]
values (Val n) = [n]
values (App _ l r) = values l ++ values r

eval :: Expr -> [Int]
eval (Val n) = [n | n > 0]
eval (App o l r) = [apply o x y |
                    x <- eval l,
                    y <- eval r,
                    valid o x y]

subs :: [a] -> [[a]]
subs [] = [[]]
subs (x:xs) = yss ++ map (x:) yss
  where yss = subs xs
        
-- perm [] = [[]]
-- perm xs = [x:ys | x <- xs, ys <- perm (delete x xs)]

interleave :: a -> [a] -> [[a]]
interleave x [] = [[x]]
interleave x (y:ys) = (x:y:ys) : map (y:) (interleave x ys)

perms :: [a] -> [[a]]
perms [] = [[]]
perms (x:xs) = concat (map (interleave x) (perms xs))

choices :: [a] -> [[a]]
choices xs = concat (map perms (subs xs))

solution :: Expr -> [Int] -> Int -> Bool
solution e ns n = elem (values e) (choices ns) && eval e == [n]

split :: [a] -> [([a], [a])]
split [] = []
split [_] = []
split (x:xs) = ([x], xs) : [(x:ls, rs) | (ls,rs) <- split xs]

exprs :: [Int] -> [Expr]
exprs [] = []
exprs [n] = [Val n]
exprs ns = [e |
           (ls,rs) <- split ns,
           l <- exprs ls,
           r <- exprs rs,
           e <- combine l r]
          
combine :: Expr -> Expr -> [Expr]
combine l r = [App o l r | o <- ops]
                
ops :: [Op]
ops = [Add, Sub, Mul, Div]

solutions :: [Int] -> Int -> [Expr]
solutions ns n = [e |
                  ns' <- choices ns,
                  e <- exprs ns'
,
                  eval e == [n]]
                 
solutions' :: [Int] -> Int -> [Expr]
solutions'
ns n = [ e |
                    ns' <- perms ns,
                    e <- exprs ns'
,
                    eval e == [n]]

-- compute 24 based on user input
-- main :: IO ()
-- main = do
-- args <- getArgs
-- print $ head $ (solutions' (map (read ) args :: [Int]) 24)


阅读(939) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~