经常跟儿子玩24点,有时候比较难算的,算一会儿,两人算不出来,就收了,当作没法算。

以我的数学能力,一般来说,算不出来的,大概率确实是算不出来的。

但是遇到比较变态的,当作算不出来是可能的,所以一直想找一个直接能解24点的程序。

可是网上找了一圈,一直没找到。

想着自己写一个,可是这里面的逻辑一直理不清楚,不知道这个算法应该怎么写。

下午坐在电脑前面想的时候,不知道为啥,像是突然开窍了。写着写着居然写出来了。

贴出来供有兴趣的朋友参考,有问题请指正。

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4.  
  5. namespace Calc24Point
  6. {
  7. internal class Program
  8. {
  9. private static void Main(string[] args)
  10. {
  11. var items = CalcHelper.CalcResult(3, 3, 8, 8);
  12. foreach (var item in items)
  13. {
  14. Console.WriteLine(item);
  15. }
  16.  
  17. Console.ReadKey();
  18. }
  19. }
  20.  
  21. public class CalcHelper
  22. {
  23. public static List<string> CalcResult(double a, double b, double c, double d)
  24. {
  25. List<string> myList = new List<string>();
  26. List<CalcInfo> items = MakeCalcs(a, b, c, d);
  27. foreach (var item in items)
  28. {
  29. var result = item.GetResult();
  30. if (double.IsNaN(result) == false && IsEqual(result, 24))
  31. {
  32. var text = item.GetString();
  33. if (myList.Contains(text) == false)
  34. {
  35. myList.Add(text);
  36. }
  37. }
  38. }
  39.  
  40. return myList;
  41. }
  42.  
  43. private static bool IsEqual(double a, double b)
  44. {
  45. return Math.Abs(a - b) < 0.000001;
  46. }
  47.  
  48. private static List<CalcInfo> MakeCalcs(double a, double b, double c, double d)
  49. {
  50. var items = new List<CalcInfo>();
  51. items.AddRange(MakeCalcs(a, (b, c, d)));
  52. items.AddRange(MakeCalcs(b, (a, c, d)));
  53. items.AddRange(MakeCalcs(c, (b, a, d)));
  54. items.AddRange(MakeCalcs(d, (b, c, a)));
  55.  
  56. return items;
  57. }
  58.  
  59. private static IEnumerable<CalcInfo> MakeCalcs(double item1, (double b, double c, double d) p)
  60. {
  61. foreach (CalcInfo item2 in MakeCalcs(p.b, (p.c, p.d)))
  62. {
  63. yield return new CalcInfo(item1, item2, EMode.加);
  64. yield return new CalcInfo(item1, item2, EMode.减);
  65. yield return new CalcInfo(item2, item1, EMode.减);
  66. yield return new CalcInfo(item1, item2, EMode.乘);
  67. yield return new CalcInfo(item1, item2, EMode.除);
  68. yield return new CalcInfo(item2, item1, EMode.除);
  69. }
  70.  
  71. foreach (CalcInfo item2 in MakeCalcs(p.c, (p.b, p.d)))
  72. {
  73. yield return new CalcInfo(item1, item2, EMode.加);
  74. yield return new CalcInfo(item1, item2, EMode.减);
  75. yield return new CalcInfo(item2, item1, EMode.减);
  76. yield return new CalcInfo(item1, item2, EMode.乘);
  77. yield return new CalcInfo(item1, item2, EMode.除);
  78. yield return new CalcInfo(item2, item1, EMode.除);
  79. }
  80.  
  81. foreach (CalcInfo item2 in MakeCalcs(p.d, (p.b, p.c)))
  82. {
  83. yield return new CalcInfo(item1, item2, EMode.加);
  84. yield return new CalcInfo(item1, item2, EMode.减);
  85. yield return new CalcInfo(item2, item1, EMode.减);
  86. yield return new CalcInfo(item1, item2, EMode.乘);
  87. yield return new CalcInfo(item1, item2, EMode.除);
  88. yield return new CalcInfo(item2, item1, EMode.除);
  89. }
  90. }
  91.  
  92. private static IEnumerable<CalcInfo> MakeCalcs(double item1, (double c, double d) p)
  93. {
  94. foreach (CalcInfo item2 in MakeCalcs(p.c, p.d))
  95. {
  96. yield return new CalcInfo(item1, item2, EMode.加);
  97. yield return new CalcInfo(item1, item2, EMode.减);
  98. yield return new CalcInfo(item2, item1, EMode.减);
  99. yield return new CalcInfo(item1, item2, EMode.乘);
  100. yield return new CalcInfo(item1, item2, EMode.除);
  101. yield return new CalcInfo(item2, item1, EMode.除);
  102. }
  103. }
  104.  
  105. private static IEnumerable<CalcInfo> MakeCalcs(double item1, double item2)
  106. {
  107. yield return new CalcInfo(item1, item2, EMode.加);
  108. yield return new CalcInfo(item1, item2, EMode.减);
  109. yield return new CalcInfo(item2, item1, EMode.减);
  110. yield return new CalcInfo(item1, item2, EMode.乘);
  111. yield return new CalcInfo(item1, item2, EMode.除);
  112. yield return new CalcInfo(item2, item1, EMode.除);
  113. }
  114. }
  115.  
  116. public class CalcInfo
  117. {
  118. public CalcInfo Items1 { get; set; }
  119. public CalcInfo Items2 { get; set; }
  120. public EMode? Mode { get; set; }
  121. public double Result { get; set; }
  122.  
  123. public CalcInfo(double value)
  124. {
  125. Result = value;
  126. }
  127.  
  128. public CalcInfo(double value1, double value2, EMode mode) : this(new CalcInfo(value1), new CalcInfo(value2), mode)
  129. {
  130. }
  131.  
  132. public CalcInfo(double value1, CalcInfo value2, EMode mode) : this(new CalcInfo(value1), value2, mode)
  133. {
  134. }
  135.  
  136. public CalcInfo(CalcInfo value1, double value2, EMode mode) : this(value1, new CalcInfo(value2), mode)
  137. {
  138. }
  139.  
  140. public CalcInfo(CalcInfo value1, CalcInfo value2, EMode mode)
  141. {
  142. Items1 = value1;
  143. Items2 = value2;
  144. Mode = mode;
  145. }
  146.  
  147. public double GetResult()
  148. {
  149. if (Mode == null)
  150. {
  151. return Result;
  152. }
  153.  
  154. var item1 = Items1.GetResult();
  155. var item2 = Items2.GetResult();
  156. if (double.IsNaN(item1) || double.IsNaN(item1))
  157. {
  158. return double.NaN;
  159. }
  160.  
  161. switch (Mode.Value)
  162. {
  163. case EMode.加:
  164. return item1 + item2;
  165. case EMode.减:
  166. return item1 - item2;
  167. case EMode.乘:
  168. return item1 * item2;
  169. case EMode.除:
  170. if (item2 == 0)
  171. {
  172. return double.NaN;
  173. }
  174.  
  175. return item1 / item2;
  176. default:
  177. Debug.Assert(false);
  178. break;
  179. }
  180.  
  181. return double.NaN;
  182. }
  183.  
  184. public string GetString()
  185. {
  186. if (Mode == null)
  187. {
  188. return Result.ToString();
  189. }
  190.  
  191. switch (Mode.Value)
  192. {
  193. case EMode.加:
  194. return $"({Items1.GetString()} + {Items2.GetString()})";
  195. case EMode.减:
  196. return $"({Items1.GetString()} - {Items2.GetString()})";
  197. case EMode.乘:
  198. return $"({Items1.GetString()} * {Items2.GetString()})";
  199. case EMode.除:
  200. return $"({Items1.GetString()} / {Items2.GetString()})";
  201. default:
  202. Debug.Assert(false);
  203. break;
  204. }
  205.  
  206. return null;
  207. }
  208. }
  209.  
  210. public enum EMode
  211. {
  212. 加,
  213. 减,
  214. 乘,
  215. 除,
  216. }
  217. }

C# 24点游戏求解算法的更多相关文章

  1. php实现 24点游戏算法

    php实现 24点游戏算法 一.总结 一句话总结:把多元运算转化为两元运算,先从四个数中取出两个数进行运算,然后把运算结果和第三个数进行运算,再把结果与第四个数进行运算.在求表达式的过程中,最难处理的 ...

  2. 24点游戏(24 game)的C++编程求解实现

    什么是24点游戏 24点游戏,英文叫做24 game,是对给定的4个非负整数进行加减乘除运算,要求每个数都要被用到且仅用到一次,并得到最终的运算结果为24.比如3.8.3.8这四个数,可以找出唯一的一 ...

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

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

  4. 经典趣味24点游戏程序设计(python)

    一.游戏玩法介绍: 24点游戏是儿时玩的主要益智类游戏之一,玩法为:从一副扑克中抽取4张牌,对4张牌使用加减乘除中的任何方法,使计算结果为24.例如,2,3,4,6,通过( ( ( 4 + 6 ) - ...

  5. cdoj 1252 24点游戏 dfs

    24点游戏 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/problem/show/1252 Descr ...

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

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

  7. 24点游戏详细截图介绍以及原型、Alpha、Beta对比

    原型设计 图片展示 功能与界面设计 1.登录注册 2.手机号验证 3.24点游戏 4.粉色系女生界面 Alpha 图片展示 功能与界面设计 1.24点游戏 2.背景音乐 3.可查看多种可能的答案 4. ...

  8. 原根求解算法 && NTT算法

    原根求解算法: 获取一个数\(N\)的原根\(root\)的算法 #include<bits/stdc++.h> #define ll long long #define IL inlin ...

  9. bzoj1215 24点游戏

    Description 为了培养小孩的计算能力,大人们经常给小孩玩这样的游戏:从1付扑克牌中任意抽出4张扑克,要小孩用“+”.“-”.“×”.“÷”和括号组成一个合法的表达式,并使表达式的值为24点. ...

随机推荐

  1. 【python】Leetcode每日一题-不同的子序列

    [python]Leetcode每日一题-不同的子序列 [题目描述] 给定一个字符串 s 和一个字符串 t ,计算在 s 的子序列中 t 出现的个数. 字符串的一个 子序列 是指,通过删除一些(也可以 ...

  2. HashSet添加操作底层判读(Object类型)

    Object类型添加操作判读 第一步:程序首先创建一个Object泛型的Set数组,这里用到了上转型: 第二步:执行object里面的add添加方法,传进的值为"JAVA": 首先 ...

  3. Asp.NetCore 自定义中间件

    这节演示一下自定义中间件,第一节我们讲到,中间件的处理流程就像一个俄罗斯套娃,那这种俄罗斯套娃型的流程内部是如何实现的呢,下面请看代码​. ​第一种写法是直接写在Configure方法中的,使用app ...

  4. 高性能MySQL-索引

    创建索引-高效索引 1.1 索引初体验 1.1.1 介绍 索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针. 索引的作用是做数据的快速检 ...

  5. c++中new[ ]与delete[ ]的分析

    前言 以前对c++的new[]的了解就是开辟一块内存,直到我最近在程序中用到它才发现我的了解太浅. 问题分析 new[]得到的内存空间不会自动初始化 new[]是在堆区中动态分配指定大小的内存,但是这 ...

  6. Linux性能调优命令之free

    功能说明 free 命令显示系统使用和空闲的内存情况,包括物理内存.交互区内存(swap)和内核缓冲区内存.共享内存将被忽略 语法 free [参数] 参数 -b : 以Byte为单位显示内存使用情况 ...

  7. 简单对比vue2.x与vue3.x响应式及新功能

    简单对比vue2.x与vue3.x响应式 对响应方式来讲:Vue3.x 将使用Proxy ,取代Vue2.x 版本的 Object.defineProperty. 为何要将Object.defineP ...

  8. DOM0和DOM2事件的应用和区别详细对比

    1.触发次数 零级事件只能注册一次,如果注册多次,后面的会覆盖前面的 btn.onclick = function () { alert(1) } btn.onclick = function () ...

  9. Tomcat的使用和配置

    Tomcat的使用 安装 在tomcat官网找到你需要用的 Tomcat 版本对应的 zip 压缩包,解压到需要安装的目录即可 目录介绍 bin : 专门用来存放Tomcat服务器的可执行文件 con ...

  10. 如何设计一个高性能 Elasticsearch mapping

    目录 前言 mapping mapping 能做什么 Dynamic mapping dynamic=true dynamic=runtime dynamic=false dynamic=strict ...