其中用到了 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点的更多相关文章

  1. hdu 1427 速算24点

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=1427 速算24点 Description 速算24点相信绝大多数人都玩过.就是随机给你四张牌,包括A( ...

  2. 24点游戏&&速算24点(dfs)

    24点游戏 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Sta ...

  3. hdu1427之速算24点

    速算24点 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Subm ...

  4. python实现算24的算法

    1.介绍 给定4个整数,数字范围在1-13之间,任意使用 + - * / ( ) ,构造出一个表达式,使得最终结果为24,这就是常见的算24的游戏.本文介绍用Python语言实现的两种方式.2.实现思 ...

  5. python 穷举法 算24点(史上最简短代码)

    本来想用回溯法实现 算24点.题目都拟好了,就是<python 回溯法 子集树模板 系列 -- 7.24点>.无奈想了一天,没有头绪.只好改用暴力穷举法. 思路说明 根据四个数,三个运算符 ...

  6. hdu 1427 速算24点 dfs暴力搜索

    速算24点 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Problem De ...

  7. Hdu1427 速算24点 2017-01-18 17:26 46人阅读 评论(0) 收藏

    速算24点 Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submiss ...

  8. HDU 1427 速算24点 (深搜)

    题目链接 Problem Description 速算24点相信绝大多数人都玩过.就是随机给你四张牌,包括A(1),2,3,4,5,6,7,8,9,10,J(11),Q(12),K(13).要求只用' ...

  9. 【Nodejs】“快算24”扑克牌游戏算法 1.02

    快算24是一种挺好的锻炼孩子算数能力的扑克牌游戏,它的游戏方式是把四张牌的牌面数值通过有限四则运算得到结果24,四张牌必须仅用一次.各地玩法还有点差别,有的只算1-10,其它抽出来:有的地方把整幅牌都 ...

随机推荐

  1. 1423 Greatest Common Increasing Subsequence (LCIS)

    讲解摘自百度; 最长公共上升子序列(LCIS)的O(n^2)算法? 预备知识:动态规划的基本思想,LCS,LIS.? 问题:字符串a,字符串b,求a和b的LCIS(最长公共上升子序列).? 首先我们可 ...

  2. 谷歌地图api訪问失败

    在非外网情况下.我们调用谷歌api会出现载入不到地图的现象.此时能够换一下域名试试或许就好了 比方我自己訪问api时时这样写的: https://maps.googleapis.com/maps/ap ...

  3. ADOX

    1.ADOX 概述 Microsoft ActiveX Data Objects Extensions for Data Definition Language and Security (ADOX) ...

  4. STS 控制台 中文乱码(maven 中文乱码)

    用uriEncoding标签设置中文字符集就行了 <plugin> <groupId>org.apache.tomcat.maven</groupId> <a ...

  5. plsql 连接oracle数据库的2种方式

      plsql 连接oracle数据库的2种方式 CreationTime--2018年8月10日09点50分 Author:Marydon 方式一:配置tnsnames.ora 该文件在instan ...

  6. 【Oracle】事务处理

    名词解释 DML:Data Manipulation Language (数据库操纵语言) 例如:DELETE.INSERT.UPDATE.SELECT DDL:Data Definition Lan ...

  7. 自己写的一个读取execl的帮助类

    目标:读取execl的第一个sheet,并传入不需要读取的表头的行数,返回该execl里所有数据的list 解析共有2种:1.DOM      2.SAX import java.io.File; i ...

  8. properties转yml

    分享一个在线properties 转 yml工具,也支持yml转properteis: http://toyaml.com/ 域名非常好记:to yaml .com yml,即yaml文本格式文件的后 ...

  9. SSO之安装CAS Server

    JA-SIG CAS(Central Authentication Service)为Web应用系统提供了单点登录服务.它的特性包括:一个开放和具有很好文档支持的协议:一个Java开源服务器组件:提供 ...

  10. Oracle-client支持exp|imp|rman

    官方精简版的驱动,不支持持exp/imp/rman,故需要安装oracle_client客户端. 实验环境: Centos6.5 x64   Oracle 11.2.0.4.0 Oracle_clie ...