=== 4月12日更新 ===

=== 先给结论吧 ===

花了近一周时间用JavaScript完成了24点去重算法,源码提交到了github上:auntyellow/24 ,可以在线试:gives you all dissimilar solutions.

在1到13范围内的四数组合中,不重复解最多的组合是2、4、8、10:

10 + 8 + 4 + 2 = 24

(10 - 4) × 8 ÷ 2 = 24

(10 × 4 + 8) ÷ 2 = 24

((10 + 2) × 8 ÷ 4 = 24

10 × 2 + 8 - 4 = 24

(10 - 2) × 4 - 8 = 24

8 × 4 - 10 + 2 = 24

(8 ÷ 4 + 10) × 2 = 24

(8 × 2 - 10) × 4 = 24

(10 - 8 ÷ 2)) × 4 = 24

10 × 4 - 8 × 2 = 24

只能用分数来解的(16个,这里不给答案了,有兴趣可以自己练练):

1, 3, 4, 6

1, 4, 5, 6 (这题居然有两解,都必须用分数的)

1, 5, 5, 5

1, 6, 6, 8

1, 8, 12, 12

2, 2, 11, 11

2, 2, 13, 13

2, 3, 5, 12

2, 4, 10, 10

2, 5, 5, 10

2, 7, 7, 10

3, 3, 7, 7

3, 3, 8, 8

4, 4, 7, 7

5, 5, 7, 11

5, 7, 7, 11

其他有难度的,就是中间过程必须有大数的(大于36就很难一下子想到了)(像a × b - a × c = 24这种形式,比如10、12、12、12,其实并没有太大难度,就没有列进去):

1, 7, 13, 13

6, 12, 12, 13

1, 6, 11, 13

6, 11, 12, 12

5, 10, 10, 13

1, 5, 11, 11

5, 10, 10, 11

4, 8, 8, 13

4, 4, 10, 10

4, 8, 8, 11

6, 9, 9, 10

3, 8, 8, 10

3, 5, 7, 13

3, 6, 6, 11

1, 2, 7, 7

5, 8, 9, 13

5, 9, 10, 11

4, 7, 11, 13

4, 9, 11, 11

4, 10, 10, 11

6, 7, 7, 11

3, 5, 8, 13

5, 5, 8, 11

2, 3, 13, 13

还找到一个难的:3、7、9、13,它有两种解法,一种用到了分数,一种有大数。

为了验证这些结论,还是查到了 @常成 那边,包括 理论 - 24理论 解决二十四点 (我的算法跟这里相当接近了)、所有独立解 - 24理论 解决二十四点 (解法最多的牌型确实有11个解),需要分数的解 - 24理论 解决二十四点 (确实有16个牌型),看来程序是没太大问题了。

=== 然后说说算法 ===

参考了本题 小于0 的回答,还有 24点算法,如何给出所有不同的答案 - 萝卜的回答 - SegmentFault ,总之就是列出所有不等价表达式,例如 (( a + b ) * c) / d 和 (( b + a) * c ) / d 是等价的,需要去重。

虽然是重复在做很多人以前做过的工作,但还是有些自认为别出心裁的思路,因为并没从代数形式上做分析,而是通过试数的办法做的,试的是π、e、lnπ和arctan e这四个超越数,对近似值做比较(浮点数运算总是有误差的)来判断两个表达式是否等价。(我把近似度设定在1e-6其实算是碰巧蒙对了,SegmentFault的萝卜指出lnπ/(e + π/arctan(e))和π/e - lnπ/arctan(e)只相差7.9e-6,如果把近似度再提高1个数量级,结果可能就不对了。)

5种括号型(((oxo)xo)xo、(ox(oxo))xo、(oxo)x(oxo)、ox((oxo)xo)、ox(ox(oxo)),其中o代表数字,x代表运算符),4个数一共有24种排列,3个符号一共有64种排列,总共需要“试数”的表达式总共有7680个,在这些表达式中找出了1170种不等价的,也和网上能找到的资料相吻合,例如 小于0 给我推荐的 A140606 - OEIS 。

后来发现,仅仅用这1170个表达式是不够的,还要考虑以下14种牌型:

a, a, b, c // 两个相同的数可以交换,也可以抵消

a, a, b, b

a, a, a, b

a, a, a, a

1, a, b, c // 1可以舍去

1, a, a, b

1, a, a, a

1, 1, a, b

1, 1, a, a

1, 1, 1, a

2, 2, a, b // 2 + 2 = 2 × 2,这个算重复解应该说得过去

2, 2, a, a

1, 2, 2, a

2, a, a, b // 2 × a - a = (a + a) ÷ 2,这个居然被我算成重复解了!

另外还有,a、a'(=a+1)、b、c这种牌型,需要把(a'-a)参与乘除运算的解法排除掉,然后单独算b+c、b*c有没有可能等于24。

所以程序里绝大部分逻辑都是在判断:牌型到底属于上面列出来的15种当中的哪一种,写得相当啰嗦。

另外还有一些小问题,比如:1、1、5、5,只给出了一种解,因为对牌型1、1、a、a组成的表达式来说, (a+1)(a-1)和a*a-1*1是等价的;

没有考虑4/2和4-2等价的问题,例如2、4、6、6,(6-(4-2))*6和(6-4/2)*6被认为是两个不等价的解(凭什么2+2和2*2等价,但4-2和4/2不等价?)

当2作为中间步骤时,没考虑2+2和2*2的等价,还拿2、4、6、6说事,(6-4+2)*6和(6-4)*2*6是不等价的解(写到这里我真后悔把2+2和2*2算做等价了)

仔细想想,还真不能轻易认为2+2=2*2、4-2=4/2是等价解法,要是真这么算的话,那么我们可以写出:

(6-4/2)*6 = (6-(4-2))*6 = (6-4+2)*6 = (6-4)*2*6

显然每个等号左右两边都是等价的。但要说最左边的和最右边的是重复的解法,那又说不过去了。

看似很简单的问题,本以为可以花半天时间搞定的,结果编码、测试、验证、优化一系列过程居然花了1周的时间,再次印证了我的盲目乐观 :-(

=== 更早的回答 ===

我在SegmentFault上提了一个相似的问题,问完才发现知乎上已经有了。很快就有人给出漂亮的解答了:24点算法,如何给出所有不同的答案 - 萝卜的回答 - SegmentFault ,起初答题者思路跟 小于0 的回答类似,后来发现穷举太麻烦,就改用符号代数,在Mathimatica里用10余行代码搞定了,真让我吃惊。

另外,对于重复解的定义,还是有挺大争论的,比如我认为2x2和2+2应该算是雷同的,但很多人并不认同。

转载一下:

Clear[game24]game24[input_List,result_:24]:=Block[{add,sub,mul,div},With[{oprules={add->Plus,sub->Subtract,mul->Times,div->Divide},specifics={div[x_,1]:>x,mul[x_,1]:>x,mul[1,x_]:>x,add[2,2]->mul[2,2]}},Map[RightComposition[Hold,ReplaceAll[oprules],ToString[#,InputForm]&,StringDelete[{"Hold[","]"}],StringReplace[{"*"->"\[Times]","/"->"\[Divide]"}]],Union[Select[result==(#/.oprules)&]@Groupings[Permutations@input,{add,sub,mul,div}->2],SameTest->(0===Simplify[sub[#1,#2]//.specifics/.Prepend[oprules,k_Integer:>ToString[k]]]&)]]]]用符号add、sub、mul、div分别对应加减乘除四则运算,构建二叉树代表算式。Groupings函数生成了所有可能的表达式二叉树。

Select筛选出计算结果符合要求的。

Union负责除去雷同的算式。它的SameTest选项计算两个代数式的差化简后是否为0。注意这里通过把数字转为字符进行“符号化”了,而且对数字1、2进行了特殊处理(specifics)。

最后Map负责把每个算式转成字符串输出。

测试:

python算24点穷举法_关于24点去重的算法?相关推荐

  1. python算24点穷举法_24点游戏7节课–第1节-游戏介绍与基本算法 | 学步园

    这仅仅是一个控制台(DOS窗口下)的小游戏--有人欢喜有人烦了.欢喜的是因为可以专心于游戏逻辑自身过程,就算你只学过C++简单的屏幕输入输出(cin.cout ),乃至换用java,C#也可以写这个小 ...

  2. python求两个数的最大公约数穷举法_五十九、如何求N个数的最大公约数和最小公倍数...

    「@Author:Runsen」 ❝ 编程的本质来源于算法,而算法的本质来源于数学,编程只不过将数学题进行代码化.「---- Runsen」 ❞ 上次介绍了短除法的因式分解,下面正式进入求解:「两个及 ...

  3. python求两个数的最大公约数穷举法_求两个数字的最大公约数-Python实现,三种方法效率比较,包含质数打印质数的方法...

    #coding:utf-8 importtime#辗转相除法: defcommonDivisor1(num1,num2):if num1 temp=num1 num1=num2 num2=tempif ...

  4. 五家共井 穷举法_第5讲地图着色问题.ppt

    部分可行解 dominating set problem The?dominating set problem?concerns testing whether γ(G)?≤?K?for a give ...

  5. 五家共井 穷举法_五户共井问题

    7623:五户共井问题 查看 提交 统计 提问 总时间限制: 1000ms 内存限制: 65536kB 描述 有A, B, C, D, E五家人共用一口井,已知井深不超过k米.A, B, C, D, ...

  6. 五家共井 穷举法_经典算法题——五家共井

    古代数学巨著<九章算数>中有这么一道题叫"五家共井,甲二绠(汲水用的井绳)不足,如(接上)乙一绠:乙三绠不足,如丙一绠: 丙四绠不足,如丁一绠:丁五绠不足,如戊一绠:戊六绠不足, ...

  7. 任务分配的穷举法、匈牙利法、分支定界法

    1.(必做)任务分配问题.设有 4 项任务 B1.B2.B3.B4,派 4 个人 A1. A2.A3.A4 去完成.每个人都可以承担 4 项任务中的任何一项,但所消耗的资金不同.设 Ai 完成 Bj ...

  8. python穷举法列举_穷举法应用举例.doc

    无 止 境 穷举法应用举例 在数学问题中, 有一些需要计算总数或种类的趣题, 因其数量关系比较隐蔽, 很难找到"正统"的方式解答,让人感到无从下手.对此,我们可以先初步估计 其数目 ...

  9. 穷举法python例子_(Python)简单线性模型与穷举优化,穷举法

    一个简单的线性模型,使用穷举法计算所有最小二乘误差,并生成分析图. import numpy as np import matplotlib.pyplot as plt # 简单线性模型-穷举法优化 ...

最新文章

  1. 利用计算机软件温度补偿,基于自主传感器信号调理芯片温度补偿的软件设计
  2. 【腾讯面试题】熊出没
  3. 一文读懂什么是数字孪生?
  4. 教你怎么修改个性开机画面
  5. flex 设置换行flex-wrap
  6. Mongodb基本操作之.net
  7. eclipse和idea代码通用吗_python能在苹果手机上运行吗
  8. 后端返回number类型数据_Javascript基础教程之数据类型 (数值 Number)
  9. 在CXF API和拦截器中添加Gzip压缩
  10. 微机原理实验1:字符串匹配程序实验
  11. VC++和VC++.NET中与图像处理有关的几个概念、结构和类
  12. Python字符串怎样实现contains效果
  13. 如何设置IntelliJ IDEA智能感知支持Jsp内置对象
  14. python maketrans函数_python中maketrans
  15. js 各种正则表达式一览表
  16. 涉密计算机清退登记表,涉密载体登记表.doc
  17. 计算机管理格式化硬盘,细说电脑怎么格式化硬盘
  18. 华为笔记本电脑触摸板失灵解决方法(触摸屏同理)
  19. 【论文翻译】Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks
  20. 桌面下雪小程序 WIN32

热门文章

  1. 2019-暑期实习生-自然语言处理算法岗-面试题
  2. Android官方开发文档Training系列课程中文版:构建第一款安卓应用之工程创建
  3. 2021-11-06深度学习
  4. Codeforces Round #263 (Div. 2) D. Appleman and Tree 树形dp
  5. codeforces 264 B. Good Sequences(dp+数学的一点思想)
  6. PDA 收银系统PDA手持打印扫描枪 销售开单 收银 扫描打印一体机
  7. Linux文件(区域)锁函数 -- open()、fcntl()
  8. Flex 流式布局 之 滚动条篇
  9. 一场关于Google不作恶信条的辩论会
  10. python如何处理视频_OpenCV-Python系列之视频处理入门