基础24点游戏规则:

从1~13中随机选取4个正整数(可以重复),通过加、减、乘、除四则运算与加括号,

使这4个正整数在每个数不多不少使用一回的情况下,经过几次运算之后算出24


1.1  实现输入式24点计算


1.1.2 实现目标:

用户输入4个用逗号分割的正整数,使程序计算能否使用这4个数在满足基础24点游戏

规则的情况下算出24,若能则输出  数学表达式,若不能则输出  抱歉,此数组无解


1.1.3 大致思路(大思路方向,具体参见代码详细注释):

(1)大致计算方向为 把符号按顺序(顺次)插入进四个数 所以,四个数的排列与三个符号及括号

的排列方式都会对结果产生影响,这时就需要进行枚举排列情况

(2)程序接收用户输入的四个数,枚举得到其所有的排列情况,统一存储在一个列表内

(3)程序再次枚举得到三个符号所有的排列情况,也统一存储在一个列表内

(4)循环取出(遍历)四个数的排列组合情况,同时在这个循环里面再套入一个循环,再循环取

出三个符号的排列组合情况,保证不漏下任何一种组合

(5)第一次,将取出的符号直接顺次插入到四个数中间,按照运算优先级来计算,看看能否得

出24

(6)如果上面的情况无法算出24,则考虑插入括号。在4个数3个运算符的式子之间,能插入两种

括号(里面包含两个数的、里面包含三个数的)

(7)通过分析运算符的排列,判定在某个地方是否需要插入括号、插入的括号有没有意义

(8)以下是分组(+即代表可以插入 +/-,×即代表可以插入 ×/÷,÷只代表插入÷(因为有特殊考

虑÷的分类),○代表插入 +/-/×/÷ 均可):

1、(a+b)×c ○ d     2、(a+b)×(c+d)    3、a÷(b+c) ○ d     4、(a+b+c)×d    5、(a+b×c)×d

6、[(a+b)×c]×d    7、(a×b+c)×d    8、[a×(b+c)]×d    9、a÷(b+c+d)    10、a÷(b×c+d)

11、a÷[b×(c+d)]    12、a÷(b+c×d)    13、a÷[(b+c)×d]   14、a ○ b ○ c ○ d


1.1.4 实际python代码("# "后面的是注释部分):

from itertools import *   #导入 itertools 模块,用于辅助排列组合时的操作while True:   #循环输入,防止输入不正确时直接结束canbreak = []   #设置变量控制是否退出 while 循环inputlist = input('24点游戏,请输入1~13中可以重复的四个整数,用一个空格隔开:').split(' ')  #获取用户输入内容,并用空格分割四个数字,存储到列表中for x in range(4):if inputlist[x].isnumeric() == False:    #如果输入的包含除数字以外内容,则重新输入print('输入内容不正确!请重新输入')print()breakelse:if int(inputlist[x]) in [1,2,3,4,5,6,7,8,9,10,11,12,13]:   #如果输入的数字在 1~13 之内,满足条件inputlist[x] = int(inputlist[x])if len(inputlist) == 4:  #如果输入了4个数canbreak.append(1)   #满足条件,设置可以退出else:   #个数不正确print('输入数字个数不正确!请重新输入')print()break else:print('输入数字大小不正确!请重新输入')    #输入的数字不在 1~13 之内,则重新输入print()breakif len(canbreak) == 4 and not(0 in canbreak):    #如果可以退出循环,则执行退出break       def GameSolve(numlist):     #定义函数,有一个参数,为一个包含四个数的列表strfoption = ''all_list = []op_list = []newlist1 = []newlist2 = []newlist3 = []op_dict={1:'+',2:'-',3:'×',4:'÷'}op_dict1={1:'+',2:'-',3:'*',4:'/'}     #以上均为设置程序所需变量,和主要运算逻辑没有太大关系for a in permutations(numlist,4):         #将 numlist(输入的包含四个数的列表排列组合)all_list.append([a[0],a[1],a[2],a[3]])      #把取出的四个数存储到列表中,这个列表用于存放四个数的所有排列方式  for x in range(1,5):         #循环取出第1个运算符for y in range(1,5):         #循环取出第2个运算符for z in range(1,5):          #循环取出第3个运算符op_list.append([x,y,z])      #将取出的三个运算符存储到列表中,这个列表用于存放三个运算符的所有排列方式   for num in all_list:        #循环从四个数的所有排列方式中,取出一种排列方式for option in op_list:        #循环从三个运算符的所有排列方式中,取出一种排列方式"""直接插入符号"""show = str(num[0])+op_dict1[option[0]]+str(num[1])+op_dict1[option[1]]+str(num[2])+op_dict1[option[2]]+str(num[3])  #直接插入符号,考虑优先级if eval(show) == 24:   #①如果直接插入符号时能算出24,则执行下面代码strfoption = str(num[0])+op_dict[option[0]]+str(num[1])+op_dict[option[1]]+str(num[2])+op_dict[option[2]]+str(num[3])  #把 "*" 替换为 "×","/" 替换为 "÷"return strfoption   #输出表达式,结束运算else:   #①的反面,即直接插入符号时不能算出24"""插入包含2个数的括号"""if (option[0] == 1 or option[0] == 2) and (option[1] == 3 or option[1] == 4):   #如果第1个符号为 +/- ,第2个符号为 ×/÷,则需要考虑括号show = '('+str(num[0])+op_dict1[option[0]]+str(num[1])+')'+op_dict1[option[1]]+str(num[2])+op_dict1[option[2]]+str(num[3])   #加入1个括号if eval(show) == 24:   #如果加上1个括号后能算出24,执行下面的代码strfoption = '('+str(num[0])+op_dict[option[0]]+str(num[1])+')'+op_dict[option[1]]+str(num[2])+op_dict[option[2]]+str(num[3])   #把 "*" 替换为 "×","/" 替换为 "÷"return strfoption   #输出表达式,结束运算elif option[2] == 1 or option[2] == 2:  #如果加上1个括号不能算出24,则再试试加上2个括号show = '('+str(num[2])+op_dict1[option[2]]+str(num[3])+')'if eval(show) != 0 or option[1] != 4:show = '('+str(num[0])+op_dict1[option[0]]+str(num[1])+')'+op_dict1[option[1]]+'('+str(num[2])+op_dict1[option[2]]+str(num[3])+')'    #加入2个括号if eval(show) == 24:    #如果加上2个括号后能算出24,执行下面的代码strfoption = '('+str(num[0])+op_dict[option[0]]+str(num[1])+')'+op_dict[option[1]]+'('+str(num[2])+op_dict[option[2]]+str(num[3])+')'  #把 "*" 替换为 "×","/" 替换为 "÷"return strfoption   #输出表达式,结束运算if option[0] == 4 and (option[1] == 1 or option[1] == 2):   #*特殊情况:如果第1个符号为 ÷,第2个符号为 +/-,也需要考虑加1个括号show = '('+str(num[1])+op_dict1[option[1]]+str(num[2])+')'  if eval(show) != 0:   #确保除数不为0show = str(num[0])+op_dict1[option[0]]+'('+str(num[1])+op_dict1[option[1]]+str(num[2])+')'+op_dict1[option[2]]+str(num[3])if eval(show) == 24:   #如果加上1个括号后能算出24,执行下面的代码strfoption = str(num[0])+op_dict[option[0]]+'('+str(num[1])+op_dict[option[1]]+str(num[2])+')'+op_dict[option[2]]+str(num[3])return strfoption   #输出表达式,结束运算"""插入包含三个数的括号"""if (option[0] == 1 or option[0] == 2) and (option[1] == 1 or option[1] == 2) and (option[2] == 3 or option[2] == 4):   #如果第1个符号为 +/-,第2个符号也为 +/-,第3个符号为 ×/÷,需考虑括号show = '('+str(num[0])+op_dict1[option[0]]+str(num[1])+op_dict1[option[1]]+str(num[2])+')'+op_dict1[option[2]]+str(num[3])   #加入1个括号if eval(show) == 24:    #如果加上1个括号后能算出24,执行下面的代码strfoption = '('+str(num[0])+op_dict[option[0]]+str(num[1])+op_dict[option[1]]+str(num[2])+')'+op_dict[option[2]]+str(num[3])  #把 "*" 替换为 "×","/" 替换为 "÷"return strfoption    #输出表达式,结束运算if ((option[0] == 1 or option[0] == 2) and (option[1] == 3 or option[1] == 4)) and (option[2] == 3 or option[2] == 4):  #如果前2个符号中有1个为 +/- ,第3个符号为 ×/÷,则也需考虑括号show = '('+str(num[0])+op_dict1[option[0]]+str(num[1])+op_dict1[option[1]]+str(num[2])+')'+op_dict1[option[2]]+str(num[3])   #加入1个括号if eval(show) == 24:    #如果加上1个括号后能算出24,执行下面的代码strfoption = '('+str(num[0])+op_dict[option[0]]+str(num[1])+op_dict[option[1]]+str(num[2])+')'+op_dict[option[2]]+str(num[3])  #把 "*" 替换为 "×","/" 替换为 "÷"return strfoption    #输出表达式,结束运算else:   #如果加上1个括号后不能算出24,则应执行下面的代码,加2个括号show = '('+'('+str(num[0])+op_dict1[option[0]]+str(num[1])+')'+op_dict1[option[1]]+str(num[2])+')'+op_dict1[option[2]]+str(num[3])  #加入2个括号if eval(show) == 24:    #如果加上2个括号后能算出24,执行下面的代码strfoption = '['+'('+str(num[0])+op_dict[option[0]]+str(num[1])+')'+op_dict[option[1]]+str(num[2])+']'+op_dict[option[2]]+str(num[3])  #把 "*" 替换为 "×","/" 替换为 "÷"return strfoption    #输出表达式,结束运算if ((option[0] == 3 or option[0] == 4) and (option[1] == 1 or option[1] == 2)) and (option[2] == 3 or option[2] == 4):    #如果前2个符号中有1个为 ×/÷,第3个符号为 +/- ,则也需考虑括号show = '('+str(num[0])+op_dict1[option[0]]+str(num[1])+op_dict1[option[1]]+str(num[2])+')'+op_dict1[option[2]]+str(num[3])   #加入1个括号if eval(show) == 24:   #如果加上1个括号后能算出24,执行下面的代码strfoption = '('+str(num[0])+op_dict[option[0]]+str(num[1])+op_dict[option[1]]+str(num[2])+')'+op_dict[option[2]]+str(num[3])   #把 "*" 替换为 "×","/" 替换为 "÷"return strfoption    #输出表达式,结束运算else:   #如果加上1个括号后不能算出24,则应执行下面的代码,加2个括号show = '('+str(num[1])+op_dict1[option[1]]+str(num[2])+')'if eval(show) != 0 or option[0] != 4:   #确保除数不为0show = '('+str(num[0])+op_dict1[option[0]]+'('+str(num[1])+op_dict1[option[1]]+str(num[2])+')'+')'+op_dict1[option[2]]+str(num[3])   #加入2个括号if eval(show) == 24:    #如果加上2个括号后能算出24,执行下面的代码strfoption = '['+str(num[0])+op_dict[option[0]]+'('+str(num[1])+op_dict[option[1]]+str(num[2])+')'+']'+op_dict[option[2]]+str(num[3])  #把 "*" 替换为 "×","/" 替换为 "÷"return strfoptionif option[0] == 4:    #如果第1个符号是 ÷ ,执行下面的代码if (option[1] == 1 or option[1] == 2) and (option[2] == 1 or option[2] == 2):  #如果第2个符号为 +/-,且第3个符号也为 +/-show = '('+str(num[1])+op_dict1[option[1]]+str(num[2])+op_dict[option[2]]+str(num[3])+')'if eval(show) != 0:  #防止除数为0show = str(num[0])+op_dict1[option[0]]+'('+str(num[1])+op_dict1[option[1]]+str(num[2])+op_dict[option[2]]+str(num[3])+')'  #加入1个括号if eval(show) == 24:   #如果加上1个括号后能算出24,执行下面的代码strfoption = str(num[0])+op_dict[option[0]]+'('+str(num[1])+op_dict[option[1]]+str(num[2])+op_dict[option[2]]+str(num[3])+')'   #把 "*" 替换为 "×","/" 替换为 "÷"return strfoption    #输出表达式,结束运算if (option[1] == 3 or option[1] == 4) and (option[2] == 1 or option[2] == 2):   #如果第2个符号为 ×/÷,且第3个符号为 +/-show = '('+str(num[1])+op_dict1[option[1]]+str(num[2])+op_dict1[option[2]]+str(num[3])+')'if eval(show) != 0:   #防止除数为0show = str(num[0])+op_dict1[option[0]]+'('+str(num[1])+op_dict1[option[1]]+str(num[2])+op_dict1[option[2]]+str(num[3])+')'   #加入1个括号if eval(show) == 24:   #如果加上1个括号后能算出24,执行下面的代码strfoption = show = str(num[1])+op_dict[option[0]]+'('+str(num[2])+op_dict[option[1]]+str(num[2])+op_dict[option[2]]+str(num[3])+')'    #把 "*" 替换为 "×","/" 替换为 "÷"return strfoption    #输出表达式,结束运算 else:    #如果加上1个括号后不能算出24,则应执行下面的代码,加2个括号  show = '('+str(num[2])+op_dict1[option[2]]+str(num[3])+')'if eval(show) != 0 or option[1] != 4:    #确保除数不为0show = '('+str(num[2])+op_dict1[option[2]]+str(num[3])+')'if eval(show) != 0:show = str(num[0])+op_dict1[option[0]]+'('+str(num[1])+op_dict1[option[1]]+'('+str(num[2])+op_dict1[option[2]]+str(num[3])+')'+')'  #加入2个括号if eval(show) == 24:    #如果加上2个括号后能算出24,执行下面的代码strfoption = str(num[0])+op_dict[option[0]]+'['+str(num[1])+op_dict[option[1]]+'('+str(num[2])+op_dict[option[2]]+str(num[3])+')'+']'     #把 "*" 替换为 "×","/" 替换为 "÷"return strfoption    #输出表达式,结束运算if (option[1] == 1 or option[1] == 2) and (option[2] == 3 or option[2] == 4):   #如果第2个符号为 +/-,且第3个符号为 ×/÷show = '('+str(num[1])+op_dict1[option[1]]+str(num[2])+op_dict1[option[2]]+str(num[3])+')'if eval(show) != 0:   #防止除数为0show = str(num[0])+op_dict1[option[0]]+'('+str(num[1])+op_dict1[option[1]]+str(num[2])+op_dict1[option[2]]+str(num[3])+')'   #加入1个括号if eval(show) == 24 or (eval(show) >= 23.99999 and eval(show) < 24):   #如果加上1个括号后能算出24 或者 23.999循环,执行下面的代码strfoption = str(num[0])+op_dict[option[0]]+'('+str(num[1])+op_dict[option[1]]+str(num[2])+op_dict[option[2]]+str(num[3])+')'    #把 "*" 替换为 "×","/" 替换为 "÷"return strfoption    #输出表达式,结束运算 else:    #如果加上1个括号后不能算出24,则应执行下面的代码,加2个括号show = '('+str(num[1])+op_dict1[option[1]]+str(num[2])+')'if eval(show) != 0:  #防止除数为0show = str(num[0])+op_dict1[option[0]]+'('+'('+str(num[1])+op_dict1[option[1]]+str(num[2])+')'+op_dict1[option[2]]+str(num[3])+')'  #加入2个括号if eval(show) == 24:    #如果加上2个括号后能算出24,执行下面的代码strfoption = str(num[0])+op_dict[option[0]]+'['+'('+str(num[1])+op_dict[option[1]]+str(num[2])+')'+op_dict[option[2]]+str(num[3])+']'     #把 "*" 替换为 "×","/" 替换为 "÷"return strfoption    #输出表达式,结束运算return '抱歉,此数组无解'   #若经过以上所有循环都没有结束运算,则意味着这四个数无法算出24,输出 "抱歉,此数组无解"print(GameSolve(inputlist))  #在屏幕上显示返回结果

1.1.5 代码补充说明

由于代码测试使用的为 python 3.9.0 IDLE环境,目前不清楚是否支持 python 2.x

另外,itertools 是 python 标准库,一般无需下载即可使用,但在某些开发软件中可能需要下载。

代码前面的 while True 部分是 输入检查 部分,用于检查用户输入内容是否符合输入要求,与24点

游戏的主逻辑无明显关系。

代码之所以没有写循环输入,是因为一次的输入能使代码更加直观,好修改,方便接下来使用。

如果想要循环输入,只需要在代码最前边(from itertools import * 下)加一个 while True: 即可


1.2  基础24点 不可解决情况种数 及 占比


1.2.2  实现目标:

程序自动枚举出所有的可能情况,稍微改变 1.1 设计的函数并调用进行计算,求出所有无解

排列的数量,与所有无解排列占所有排列的比重


1.2.3 大致思路(大思路方向,具体参见代码注释):

(1)程序在 1~13 中枚举四个数的所有排列方式,并统一存储到一个列表中

(2)程序调用 1.1 GameSolve 函数确定该组合是否无解

(3)由于只需要确定组合是否无解,不需要输出表达式,可以对 GameSolve 函数的 回推确定表

达式 一段进行修改/删除,把返回值改为 0/1 即可。

(4)可以适当修改 GameSolve 函数的返回值,这样可以简化程序判断是否无解的过程

(5)循环取出四个数所有的排列方式,并将其输入到 GameSolve 函数中,进行计算

(6)程序接收返回值,也统一存储到一个列表中

(7)循环取出返回值,程序进行判断,输出结论


1.2.4  实际python代码("#" 后面的是注释部分):

from itertools import *   #导入 itertools 模块,用于辅助排列组合时的操作     def GameSolve(numlist):     #定义函数,有一个参数,为一个包含四个数的列表strfoption = ''all_list = []op_list = []newlist1 = []newlist2 = []newlist3 = []op_dict={1:'+',2:'-',3:'×',4:'÷'}op_dict1={1:'+',2:'-',3:'*',4:'/'}     #以上均为设置程序所需变量,和主要运算逻辑没有太大关系for a in permutations(numlist,4):         #将 numlist(输入的包含四个数的列表排列组合)all_list.append([a[0],a[1],a[2],a[3]])      #把取出的四个数存储到列表中,这个列表用于存放四个数的所有排列方式  for x in range(1,5):         #循环取出第1个运算符for y in range(1,5):         #循环取出第2个运算符for z in range(1,5):          #循环取出第3个运算符op_list.append([x,y,z])      #将取出的三个运算符存储到列表中,这个列表用于存放三个运算符的所有排列方式   for num in all_list:        #循环从四个数的所有排列方式中,取出一种排列方式for option in op_list:        #循环从三个运算符的所有排列方式中,取出一种排列方式"""直接插入符号"""show = str(num[0])+op_dict1[option[0]]+str(num[1])+op_dict1[option[1]]+str(num[2])+op_dict1[option[2]]+str(num[3])  #直接插入符号,考虑优先级if eval(show) == 24:   #①如果直接插入符号时能算出24,则执行下面代码  return 1   else:   #①的反面,即直接插入符号时不能算出24"""插入包含2个数的括号"""if (option[0] == 1 or option[0] == 2) and (option[1] == 3 or option[1] == 4):   #如果第1个符号为 +/- ,第2个符号为 ×/÷,则需要考虑括号show = '('+str(num[0])+op_dict1[option[0]]+str(num[1])+')'+op_dict1[option[1]]+str(num[2])+op_dict1[option[2]]+str(num[3])   #加入1个括号if eval(show) == 24:   #如果加上1个括号后能算出24,执行下面的代码  return 1   elif option[2] == 1 or option[2] == 2:  #如果加上1个括号不能算出24,则再试试加上2个括号show = '('+str(num[2])+op_dict1[option[2]]+str(num[3])+')'if eval(show) != 0 or option[1] != 4:show = '('+str(num[0])+op_dict1[option[0]]+str(num[1])+')'+op_dict1[option[1]]+'('+str(num[2])+op_dict1[option[2]]+str(num[3])+')'    #加入2个括号if eval(show) == 24:    #如果加上2个括号后能算出24,执行下面的代码  return 1   if option[0] == 4 and (option[1] == 1 or option[1] == 2):   #*特殊情况:如果第1个符号为 ÷,第2个符号为 +/-,也需要考虑加1个括号show = '('+str(num[1])+op_dict1[option[1]]+str(num[2])+')'  if eval(show) != 0:   #确保除数不为0show = str(num[0])+op_dict1[option[0]]+'('+str(num[1])+op_dict1[option[1]]+str(num[2])+')'+op_dict1[option[2]]+str(num[3])if eval(show) == 24:   #如果加上1个括号后能算出24,执行下面的代码return 1   """插入包含三个数的括号"""if (option[0] == 1 or option[0] == 2) and (option[1] == 1 or option[1] == 2) and (option[2] == 3 or option[2] == 4):   #如果第1个符号为 +/-,第2个符号也为 +/-,第3个符号为 ×/÷,需考虑括号show = '('+str(num[0])+op_dict1[option[0]]+str(num[1])+op_dict1[option[1]]+str(num[2])+')'+op_dict1[option[2]]+str(num[3])   #加入1个括号if eval(show) == 24:    #如果加上1个括号后能算出24,执行下面的代码 return 1    if ((option[0] == 1 or option[0] == 2) and (option[1] == 3 or option[1] == 4)) and (option[2] == 3 or option[2] == 4):  #如果前2个符号中有1个为 +/- ,第3个符号为 ×/÷,则也需考虑括号show = '('+str(num[0])+op_dict1[option[0]]+str(num[1])+op_dict1[option[1]]+str(num[2])+')'+op_dict1[option[2]]+str(num[3])   #加入1个括号if eval(show) == 24:    #如果加上1个括号后能算出24,执行下面的代码 return 1    else:   #如果加上1个括号后不能算出24,则应执行下面的代码,加2个括号show = '('+'('+str(num[0])+op_dict1[option[0]]+str(num[1])+')'+op_dict1[option[1]]+str(num[2])+')'+op_dict1[option[2]]+str(num[3])  #加入2个括号if eval(show) == 24:    #如果加上2个括号后能算出24,执行下面的代码return 1    if ((option[0] == 3 or option[0] == 4) and (option[1] == 1 or option[1] == 2)) and (option[2] == 3 or option[2] == 4):    #如果前2个符号中有1个为 ×/÷,第3个符号为 +/- ,则也需考虑括号show = '('+str(num[0])+op_dict1[option[0]]+str(num[1])+op_dict1[option[1]]+str(num[2])+')'+op_dict1[option[2]]+str(num[3])   #加入1个括号if eval(show) == 24:   #如果加上1个括号后能算出24,执行下面的代码   return 1    else:   #如果加上1个括号后不能算出24,则应执行下面的代码,加2个括号show = '('+str(num[1])+op_dict1[option[1]]+str(num[2])+')'if eval(show) != 0 or option[0] != 4:   #确保除数不为0show = '('+str(num[0])+op_dict1[option[0]]+'('+str(num[1])+op_dict1[option[1]]+str(num[2])+')'+')'+op_dict1[option[2]]+str(num[3])   #加入2个括号if eval(show) == 24:    #如果加上2个括号后能算出24,执行下面的代码 return 1if option[0] == 4:    #如果第1个符号是 ÷ ,执行下面的代码if (option[1] == 1 or option[1] == 2) and (option[2] == 1 or option[2] == 2):  #如果第2个符号为 +/-,且第3个符号也为 +/-show = '('+str(num[1])+op_dict1[option[1]]+str(num[2])+op_dict[option[2]]+str(num[3])+')'if eval(show) != 0:  #防止除数为0show = str(num[0])+op_dict1[option[0]]+'('+str(num[1])+op_dict1[option[1]]+str(num[2])+op_dict[option[2]]+str(num[3])+')'  #加入1个括号if eval(show) == 24:   #如果加上1个括号后能算出24,执行下面的代码return 1    if (option[1] == 3 or option[1] == 4) and (option[2] == 1 or option[2] == 2):   #如果第2个符号为 ×/÷,且第3个符号为 +/-show = '('+str(num[1])+op_dict1[option[1]]+str(num[2])+op_dict1[option[2]]+str(num[3])+')'if eval(show) != 0:   #防止除数为0show = str(num[0])+op_dict1[option[0]]+'('+str(num[1])+op_dict1[option[1]]+str(num[2])+op_dict1[option[2]]+str(num[3])+')'   #加入1个括号if eval(show) == 24:   #如果加上1个括号后能算出24,执行下面的代码   return 1     else:    #如果加上1个括号后不能算出24,则应执行下面的代码,加2个括号  show = '('+str(num[2])+op_dict1[option[2]]+str(num[3])+')'if eval(show) != 0 or option[1] != 4:    #确保除数不为0show = '('+str(num[2])+op_dict1[option[2]]+str(num[3])+')'if eval(show) != 0:show = str(num[0])+op_dict1[option[0]]+'('+str(num[1])+op_dict1[option[1]]+'('+str(num[2])+op_dict1[option[2]]+str(num[3])+')'+')'  #加入2个括号if eval(show) == 24:    #如果加上2个括号后能算出24,执行下面的代码 return 1    if (option[1] == 1 or option[1] == 2) and (option[2] == 3 or option[2] == 4):   #如果第2个符号为 +/-,且第3个符号为 ×/÷show = '('+str(num[1])+op_dict1[option[1]]+str(num[2])+op_dict1[option[2]]+str(num[3])+')'if eval(show) != 0:   #防止除数为0show = str(num[0])+op_dict1[option[0]]+'('+str(num[1])+op_dict1[option[1]]+str(num[2])+op_dict1[option[2]]+str(num[3])+')'   #加入1个括号if eval(show) == 24 or (eval(show) >= 23.99999 and eval(show) < 24):   #如果加上1个括号后能算出24 或者 23.999循环,执行下面的代码(python 没有分数的数据类型,所以要考虑 0.9999… = 1 的情况)return 1     else:    #如果加上1个括号后不能算出24,则应执行下面的代码,加2个括号show = '('+str(num[1])+op_dict1[option[1]]+str(num[2])+')'if eval(show) != 0:  #防止除数为0show = str(num[0])+op_dict1[option[0]]+'('+'('+str(num[1])+op_dict1[option[1]]+str(num[2])+')'+op_dict1[option[2]]+str(num[3])+')'  #加入2个括号if eval(show) == 24:    #如果加上2个括号后能算出24,执行下面的代码   return 1    return 0   #如果以上循环结束后仍没有结束运算,则说明此排列无解,输出0all_numlist = []
all_returnlist = []   #以上为赋值部分,与主要逻辑没有太大关系for a in range(1,14):for b in range(a,14):      #之所以不用 (1,14) 而用 (a,14),是因为这里不考虑先后顺序(1,1,2,3 和 2,3,1,1 是同一种,这种先后排列情况 GameSolve 函数自动考虑)for c in range(b,14):for d in range(c,14):all_numlist.append([a,b,c,d])   #循环四次取出 1~13 这13个数中的1个数,取出后将4个数统一存储在一个列表里(枚举4个数所有的排列与组合方式)for numlist in all_numlist:all_returnlist.append(GameSolve(numlist))   #循环取出 4个数的排列情况 ,调用 GameSolve 函数,验证这种排列情况是否可以算出24,并统一将结果存储到一个列表内no_answer = all_returnlist.count(0)   #无解排列个数(因为不能算出24返回0,能算出24返回1,所以直接 count 统计列表内有多少个 0 即可)
all_answer = len(all_returnlist)   #总共排列个数(因为不管能不能算出24都有返回值,所以直接看列表有多长(有多少个元素)即可)
percentlist = list(str(no_answer/all_answer))   #用算不出来24的可能数除以总共的可能数,即可得到一个小数
percent = percentlist[2]+percentlist[3]+'.'+percentlist[4]+percentlist[5]+'%'   #无解排列占比(截取这个小数小数点后的四位(没有四舍五入),加上百分号,将其化为百分数)print('无解排列个数:'+str(no_answer))   #输出 无解排列个数
print('总共排列个数:'+str(all_answer))   #输出 总共排列个数
print('无解排列占比:'+percent)              #输出 无解排列占比

1.2.5  代码补充说明

结论:无解排列个数 458,总共排列个数 1820,无解排列占比 25.16%

此结论为 不考虑花色,只考虑数值 情况下的结论,即将 不同花色但牌值一样的牌 都视为一张牌

代码主要采用笨枚举的方式,所以运行速度较慢,大约需要 3分20秒 才能显示出结果

此代码结果只显示 无解排列个数 总共排列个数 无解排列占比

如需了解详细数组,可以参照24点运算无解表


发文不易,点个赞再走吧~

24点_24点研究_24点结论_python相关推荐

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

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

  2. PostgreSQL 10.1 手册_部分 III. 服务器管理_第 24 章 日常数据库维护工作_24.3. 日志文件维护...

    24.3. 日志文件维护 把数据库服务器的日志输出保存在一个地方是个好主意, 而不是仅仅通过/dev/null丢弃它们. 在进行问题诊断的时候,日志输出是非常宝贵的.不过,日志输出可能很庞大(特别是在 ...

  3. 24口光纤配线架 cad块_24口光纤配线架定义

    24 口光纤配线架又叫光纤终端盒, 24 口光纤配线架是高密度,大容量设计,它 具有外型美观大方,分配合理,便于查找,管理容易,安装方便及良好的操作性 等特点. 24 口光纤配线架主要分为: FC 型 ...

  4. 人工智能对医疗行业影响的专题研究:基本结论

    来源:本翼资本    概要:从未来5-7年的中期来看,我们认为计算智能和部分感知智能将迎来机会,计算智能的基因检测和药物发现.感知智能中的医疗智能语音.医疗智能视觉.可穿戴医疗设备等将迎来爆发. 从未 ...

  5. 子进程和父进程的结论_Python的多进程不是随便用滴!

    python在处理任务时是带有多线程和多进程的,Python不管是多线程还是多进程都不咋好用,不然自导的django也不会初始化时的并发效率不高.今天我们主要来看下Python的多进程. 首先大家先要 ...

  6. python的研究方法有哪些_python有哪些提取文本摘要的库

    展开全部 1.2113google goose >>> from goose import Goose >>> url = 'http://edition.cnn. ...

  7. python实验结论_Python基础(上)实验报告

    写在前面:这是Python语言的学习之路,大家可以跟着一起学习,绝对是从零开始. Gvim (图形化界面Vim) Brackets(前端友好编辑器) Gedit(编辑器) 使用环境 python 2. ...

  8. python论文结论_Python学习总结

    在过去的两周,通过对python基础知识的学习以及通过一个具体的小游戏的练习,大概对Python有了一个初步的了解,在这里做一个总结,希望对今后的进一步学习有帮助. 之前学习过C语言,在学习了Pyth ...

  9. python投掷骰子实验实验结论_Python 投掷骰子,并用pygal制图画出统计结果

    首先是diee.py文件 #coding:gbk from random import randint class Die(): '''创建一个骰子的类''' def __init__(self,nu ...

最新文章

  1. python从菜鸟到高手电子书下载_PYTHON从菜鸟到高手 清华大学出版社
  2. 我来说说14届竞赛内容,别拍勿喷
  3. P1852-跳跳棋【思维,差分,二分】
  4. android 日程安排view,RecyclerView 列表控件中简单实现时间线
  5. SpringMVC 控制层注解
  6. python核心编程怎么做_Python核心编程:8个实践性建议
  7. java中runnable_Java中Runnable和Thread的区别
  8. 数据结构与算法之-----图(拓扑排序)
  9. GitHub的实现是否是基于此语言的支持网络编程性呢?
  10. Hadoop 技术在电信运营商上网日志处理中的应用架构
  11. 进程与线程之间最深入形象的比喻
  12. 联想USB键盘功能键驱动问题
  13. MATLAB数字图像处理
  14. Redies tutorial
  15. MYSQL 索引 主键 外键
  16. 生活之美--需要设计
  17. 释放数字生产力 引领数字化转型新纪元——弘玑Cyclone 2022产品发布会圆满落幕
  18. 一键root大师 android,一键Root大师
  19. 【凡是过去 皆为序章】 回顾大二刚开学的心路历程
  20. 关于计算机网络简笔画,玩电脑简笔画图片

热门文章

  1. 什么是三层交换机?二层交换与三层交换和路由有什么区别?
  2. matlab 双边沿滤波,一种基于数字PWM发生器的左增长双边沿UPWM信号频谱估计方法与流程...
  3. 国家食品药品监督管理局 前有27家网站有资格向个人销售非处方药
  4. ISO OSI IOS 傻傻分不清楚【每日打卡小知识】
  5. 谁是谷歌想要的人才--面试
  6. 用java实现坏巧克力问题,【原料】关于巧克力在使用中出现的问题详解
  7. 基于SSH架构的在线答疑系统
  8. zx-quill+vue+element实现富文本图片上传到服务器
  9. GitLab CI/CD artifacts 属性的配置与使用
  10. 【自动驾驶】1.V2X、OBU、RSU、V2V之间的协作关系