初学 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)-无法直接启动带有类库输出类型的项目怎么办
我把Driver.cs文件去掉了一行注释,发现报错 右击这个解决方案,选择属性,然后再启动项目中改成MySample 更多教学视频和资料下载,欢迎关注以下信息: 我的优酷空间: http:// ...
- 破解无线网络密码-BT3如何使用3
BT3 虚拟机 SNOOPWEP2 破解无线网络WEP密钥图解 1.下载BT3 光盘映像文件(ISO格式),比如:bt3-final.iso: 用WinISO 或 UltraISO(这个还支持DVD ...
- PHP高级教程-文件上传
PHP 文件上传 通过 PHP,可以把文件上传到服务器. 本章节实例在 test 项目下完成,目录结构为: test |-----upload # 文件上传的目录 |-----form.html # ...
- 分享几个.NET 下的计划任务组件
Quartz http://www.quartz-scheduler.net/(现项目在使用,可以看我之前的文章) Hangfire http://hangfire.io/ Install-Packa ...
- SQL:1999基本语法(学习笔记)
SQL:1999基本语法 SELECT [DISTINCT] * | 列名称 [AS]别名,........ FROM 表名称1 [别名1][CROSS JOIN表名称2 别名2]| [NATURAL ...
- java面试第九天
图形界面: 布局管理器: CardLayout:卡片布局,面板重叠放置,只能看到一个,最先添加的会被显示出来,可以进行翻动 两种构造方法: CardLayout() 创建一个间隙大小为 0 的新卡片布 ...
- java统计abacbacdadbc中的每个字母出现的次数,输出格式是:a(4)b(3)c(3)d(2)
import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.TreeMap; /* ...
- 深入理解索引系列1:B+树
- JavaSE入门学习17:Java面向对象之package(包)
一Java包(package) 为了更好地组织类,Java提供了包机制,用于差别类名的命名空间. 包的作用: A把功能类似或相关的类或接口组织在 ...
- cocos2d-x项目101次相遇-安装和环境搭建 -xcode
cocos2d-x 101次相遇 / 文件夹 1 安装和环境搭建 -xcode 2 Scenes . Director, Layers, Sprites 3 建立图片菜单 4 在 ...