初学 Haskell 练习:算24点
其中用到了 Monad 做不确定性计算。运行速度很快。
-- woodfox, Oct 10, 2014
import Control.Applicative
import Control.Monad
import Data.List
operators = [("+", (+)), ("-", (-)), ("*", (*)), ("/", (/))]
find_op :: String -> (Float -> Float -> Float)
find_op op_name = let (k, v):[] = filter (\(name, op) -> name == op_name) operators
in v
compose :: [Float] -> [String] -> [(Float, String)]
compose nums op_names = let a:b:c:d:[] = nums
f1name:f2name:f3name:[] = op_names
f1:f2:f3:[] = map find_op op_names
r1 = f3 (f1 a b) (f2 c d)
s1 = "(" ++ show a ++ f1name ++ show b ++ ")" ++ f3name ++ "(" ++ show c ++ f2name ++ show d ++ ")"
r2 = f3 (f2 (f1 a b) c) d
s2 = "((" ++ show a ++ f1name ++ show b ++ ")" ++ f2name ++ show c ++ ")" ++ f3name ++ show d
r3 = f3 (f2 a (f1 b c)) d
s3 = "(" ++ show a ++ f2name ++ "(" ++ show b ++ f1name ++ show c ++ "))" ++ f3name ++ show d
r4 = f3 a (f2 (f1 b c) d)
s4 = show a ++ f3name ++ "((" ++ show b ++ f1name ++ show c ++ ")" ++ f2name ++ show d ++ ")"
r5 = f3 a (f2 b (f1 c d))
s5 = show a ++ f3name ++ "(" ++ show b ++ f2name ++ "(" ++ show c ++ f1name ++ show d ++ "))"
in [(r1,s1), (r2,s2), (r3,s3), (r4,s4), (r5,s5)]
-- http://stackoverflow.com/questions/11358979/list-permutations-in-haskell
permute :: Eq a => [a] -> [[a]]
permute [] = [[]]
permute xs = concatMap (\x -> map (x:) $ permute $ delete x xs) xs
calc24 :: [Float] -> [String]
calc24 nums = do
-- i <- nums
-- j <- nums
-- m <- nums
-- n <- nums
-- guard (i /= j && i /= m && i /= n && j /= m && j /= n && m /= n)
i:j:m:n:[] <- (permute nums)
(f1name, _) <- operators
(f2name, _) <- operators
(f3name, _) <- operators
(result, str) <- (compose [i,j,m,n] [f1name, f2name, f3name])
-- guard (result == 24)
guard (abs (result - 24) < 0.00001)
return str
测试:
*Main> calc24 [5,6,7,8]
["(5.0+7.0)*(8.0-6.0)","((5.0+7.0)-8.0)*6.0","(5.0+(7.0-8.0))*6.0","((5.0-8.0)+7.0)*6.0","(5.0-(8.0-7.0))*6.0","6.0*((5.0+7.0)-8.0)","6.0*(5.0+(7.0-8.0))","6.0*((5.0-8.0)+7.0)","6.0*(5.0-(8.0-7.0))","6.0*((7.0+5.0)-8.0)","6.0*(7.0+(5.0-8.0))","(6.0/(7.0-5.0))*8.0","6.0/((7.0-5.0)/8.0)","6.0*((7.0-8.0)+5.0)","6.0*(7.0-(8.0-5.0))","6.0*(8.0/(7.0-5.0))","(6.0*8.0)/(7.0-5.0)","(7.0+5.0)*(8.0-6.0)","((7.0+5.0)-8.0)*6.0","(7.0+(5.0-8.0))*6.0","((7.0-8.0)+5.0)*6.0","(7.0-(8.0-5.0))*6.0","(8.0-6.0)*(5.0+7.0)","(8.0-6.0)*(7.0+5.0)","8.0*(6.0/(7.0-5.0))","(8.0*6.0)/(7.0-5.0)","(8.0/(7.0-5.0))*6.0","8.0/((7.0-5.0)/6.0)"]
*Main> calc24 [8,10,3,2]
["(8.0+10.0)+(3.0*2.0)","8.0+(10.0+(3.0*2.0))","(8.0+10.0)+(2.0*3.0)","8.0+(10.0+(2.0*3.0))","(8.0+(3.0*2.0))+10.0","8.0+((3.0*2.0)+10.0)","(8.0+(2.0*3.0))+10.0","8.0+((2.0*3.0)+10.0)","(10.0+8.0)+(3.0*2.0)","10.0+(8.0+(3.0*2.0))","(10.0+8.0)+(2.0*3.0)","10.0+(8.0+(2.0*3.0))","((10.0*3.0)-8.0)+2.0","(10.0*3.0)-(8.0-2.0)","(10.0+(3.0*2.0))+8.0","10.0+((3.0*2.0)+8.0)","((10.0*3.0)+2.0)-8.0","(10.0*3.0)+(2.0-8.0)","(10.0+(2.0*3.0))+8.0","10.0+((2.0*3.0)+8.0)","((3.0*10.0)-8.0)+2.0","(3.0*10.0)-(8.0-2.0)","((3.0*10.0)+2.0)-8.0","(3.0*10.0)+(2.0-8.0)","(3.0*2.0)+(8.0+10.0)","((3.0*2.0)+8.0)+10.0","(3.0*2.0)+(10.0+8.0)","((3.0*2.0)+10.0)+8.0","(2.0-8.0)+(10.0*3.0)","2.0-(8.0-(10.0*3.0))","(2.0-8.0)+(3.0*10.0)","2.0-(8.0-(3.0*10.0))","(2.0+(10.0*3.0))-8.0","2.0+((10.0*3.0)-8.0)","(2.0*3.0)+(8.0+10.0)","((2.0*3.0)+8.0)+10.0","(2.0*3.0)+(10.0+8.0)","((2.0*3.0)+10.0)+8.0","(2.0+(3.0*10.0))-8.0","2.0+((3.0*10.0)-8.0)"]
补充一个测试,3,3,8,8 算 24点可以得到正确答案(已修正):
*Main> calc24 [3,3,8,8]
["8.0/(3.0-(8.0/3.0))","8.0/(3.0-(8.0/3.0))","8.0/(3.0-(8.0/3.0))","8.0/(3.0-(8.0/3.0))"]
初学 Haskell 练习:算24点的更多相关文章
- hdu 1427 速算24点
题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=1427 速算24点 Description 速算24点相信绝大多数人都玩过.就是随机给你四张牌,包括A( ...
- 24点游戏&&速算24点(dfs)
24点游戏 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submit Sta ...
- hdu1427之速算24点
速算24点 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Subm ...
- python实现算24的算法
1.介绍 给定4个整数,数字范围在1-13之间,任意使用 + - * / ( ) ,构造出一个表达式,使得最终结果为24,这就是常见的算24的游戏.本文介绍用Python语言实现的两种方式.2.实现思 ...
- python 穷举法 算24点(史上最简短代码)
本来想用回溯法实现 算24点.题目都拟好了,就是<python 回溯法 子集树模板 系列 -- 7.24点>.无奈想了一天,没有头绪.只好改用暴力穷举法. 思路说明 根据四个数,三个运算符 ...
- hdu 1427 速算24点 dfs暴力搜索
速算24点 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Problem De ...
- Hdu1427 速算24点 2017-01-18 17:26 46人阅读 评论(0) 收藏
速算24点 Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other) Total Submiss ...
- HDU 1427 速算24点 (深搜)
题目链接 Problem Description 速算24点相信绝大多数人都玩过.就是随机给你四张牌,包括A(1),2,3,4,5,6,7,8,9,10,J(11),Q(12),K(13).要求只用' ...
- 【Nodejs】“快算24”扑克牌游戏算法 1.02
快算24是一种挺好的锻炼孩子算数能力的扑克牌游戏,它的游戏方式是把四张牌的牌面数值通过有限四则运算得到结果24,四张牌必须仅用一次.各地玩法还有点差别,有的只算1-10,其它抽出来:有的地方把整幅牌都 ...
随机推荐
- BZOJ 3172 Tjoi2013 单词 后缀数组
题目大意:给定一个n个单词的文章,求每一个单词在文章中的出现次数 文章长度<=10^6(不是单词长度<=10^6,不然读入直接超时) 首先将全部单词用空格连接成一个字符串.记录每一个单词的 ...
- Linux之nohup命令:实现退出终端后程序继续后台运行
转自:http://tech.ccidnet.com/art/302/20070618/1115599_1.html 简单而有用的nohup命令在UNIX/LINUX中,普通进程用&符号放到后 ...
- Hibernate常用查询语句
Hibernate常用查询语句 Hib的检索方式1'导航对象图检索方式.通过已经加载的对象,调用.iterator()方法可以得到order对象如果是首次执行此方法,Hib会从数据库加载关联的orde ...
- 如何使用屏幕取色工具ColorPixl
ColorPix可以屏幕取色,假如现在想要取色桌面徽标键的颜色,按任意键可以锁定这个区域(press any key to lock)这样我们就可以在放大的区域更清楚的取色,加号按钮可以设置该软件是否 ...
- Java多线程之生产者消费者问题<一>:使用synchronized keyword解决生产者消费者问题
今天看了一片博文,讲Java多线程之线程的协作,当中作者用程序实例说明了生产者和消费者问题,但我及其它读者发现程序多跑几次还是会出现死锁,百度搜了下大都数的样例也都存在bug,经过细致研究发现当中的问 ...
- POSIX 线程 – pthread_sigmask
http://www.cnblogs.com/qq78292959/archive/2012/04/05/2432985.html 概念 按照 POSIX, 异步 (外部) 信号发送到整个进程. 所有 ...
- STL 源代码剖析 算法 stl_algo.h -- partial_sort / partial_sort_copy
本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie partial_sort / partial_sort_copy ------------- ...
- HTML解析模块
import html html.escape(s, quote=True) 对特殊字符进行转义 Convert the characters &, < and > in stri ...
- TP框架中APP_SUB_DOMAIN_DEPLOY什么意思?
'APP_SUB_DOMAIN_DEPLOY' => false, // 是否开启子域名部署 thinkphp开启域名部署/子域名部署/泛域名部署/IP访问部署 Think ...
- alipay
//安装 插件cordova plugin add https://github.com/charleyw/cordova-plugin-alipay.git --variable PARTNER_I ...