初学 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,其它抽出来:有的地方把整幅牌都 ...
随机推荐
- C#.NET常见问题(FAQ)-浮点数如何四舍五入
使用Math.Round方法即可实现保留指定的小数点后面位数,这种方法返回的还是double类型,而ToString方法并没有做实际转换 更多教学视频和资料下载,欢迎关注以下信息: 我的优酷空间: ...
- Python编程-Office操作-操作Excel(中)
例子文件如下: 一些复杂的读取操作getCells.py import openpyxl wb = openpyxl.load_workbook('example.xlsx') sheet = wb. ...
- JSP实现数据传递(web基础学习笔记三)
get和post的区别: JSP内置对象: 1)out内置对象:out内置对象是在JSP开发过程中使用得最为频繁的对象,然而其使用起来也是最简单的.out对象用于向客户端浏览器输出数 ...
- TP自动生成模块目录
TP自动生成模块目录 例如我想在项目中增加一个AdminI模块 只需要在入口文件index.php中添加: define('BIND_MODULE','Admin'); 再访问127.0.0.1项目就 ...
- VB中如何修改treeview的背景色
改变 TreeView 的背景 Private Declare Function SendMessage Lib "User32" Alias "SendMessa ...
- iOS调试证书/公布证书制作
当已经注冊过applied 开发人员账号后,而且进行付款了,那么接下来就是证书制作了 1.登录membercenter https://developer.apple.com/membercenter ...
- Java 基础【11】.class getClass () forName() 详解
类名.class是Class对象的句柄,每个被加载的类,在jvm中都会有一个Class对象与之相对应. 如果要创建新的对象,直接使用Class对象的局部class.forName就可以了,不需要用ne ...
- Java的代理模式(通过公共接口实现)
代理模式的一种常见的实现方案是,定义一个接口或抽象类,并派生出目标子类,和代理子类.我们要操作的是目标子类里的方法,而很多时候,我们需要为目录子类中的方法增加额外的处理,如果增加日志功能.条件判断等, ...
- Oracle 11g 更改字符集
查看字符集: select * from v$nls_parameters where parameter = 'NLS_CHARACTERSET'; 修改字符集: sqlplus "/as ...
- 【Oracle】锁
Oracle所有锁的分配和管理都是数据库管理系统自动完成的,不需要用户进行干预. v$lock表说明 字段 描述 ADDR Address of lock state object KADDR Add ...