Python實現(xiàn)快速計算24點游戲的示例代碼
24 點游戲規(guī)則
有4個范圍在 [1,9] 的數(shù)字,通過「加、減、乘、除」四則運算能夠獲得24,認為有解。
4個范圍在 [1,9] 的數(shù)字能夠產(chǎn)生495種可能,其中404中組合情況都是有解的,有解概率高達81.62%。
下面我們用python來驗證它,首先計算組合數(shù):
from scipy.special import comb comb(9, 4, repetition=True)
495.0
可以看到python計算出9個數(shù)字有重復(fù)的組合情況數(shù)是495。
下面我們需要一個方法,判斷4個數(shù)字能否組合成為24點,這里我采用回溯算法進行計算。
回溯算法計算思路
首先從4個數(shù)字中選擇2個數(shù)字,然后再選擇一種運算操作,然后用得到的結(jié)果取代選出的2個數(shù)字。然后在剩下的3個數(shù)字中,進行同樣的操作。依次類推,最終計算到只剩一個數(shù)字,看結(jié)果是否為24即可。
開始編碼:
from operator import add, mul, sub, truediv
ops = [add, mul, sub, truediv]
def judgePoint24(nums) -> bool:
if not nums:
return False
n = len(nums)
if n == 1:
return round(nums[0], 3) == 24
for i, j in permutations(range(n), 2):
# 選2個數(shù)字
x, y = nums[i], nums[j]
newNums = []
# 選擇加減乘除 4 種運算操作之一,用得到的結(jié)果取代選出的 2 個數(shù)字
for k, z in enumerate(nums):
if k != i and k != j:
newNums.append(z)
for k in range(4):
if k < 2 and i > j:
# 加法和乘法滿足交換律,跳過第二種順序
continue
if k == 3 and round(y, 3) == 0:
# 除法運算除數(shù)不能為0
continue
newNums.append(ops[k](x, y))
if judgePoint24(newNums):
return True
newNums.pop()
return False
然后我們遍歷所有的組合進行判斷:
from scipy.special import comb
???????total = int(comb(9, 4, repetition=True))
cnt = sum(judgePoint24(nums)
for nums in combinations_with_replacement(range(1, 10), 4))
print(f'{cnt}/{total}={cnt/total:.2%}')
最終一秒內(nèi)計算出結(jié)果:

生成表達式
下面我們加大難度,要求在求解時,能夠同時返回可行的表達式。暴力遍歷固然可以實現(xiàn),但是耗時太長,能否在這種回溯算法的基礎(chǔ)上實現(xiàn)呢?
我的思路是加個變量記錄每次的選擇,最終再通過一定的技巧進行還原,最終編碼:
from operator import add, mul, sub, truediv
from itertools import permutations, combinations_with_replacement
from collections import defaultdict
def judgePoint24(nums) -> bool:
ops = [add, mul, sub, truediv]
op_char = "+*-/"
record = []
def solve(nums) -> bool:
if not nums:
return False
n = len(nums)
if n == 1:
return round(nums[0], 3) == 24
for i, j in permutations(range(n), 2):
# 選2個數(shù)字
x, y = nums[i], nums[j]
newNums = []
# 選擇加減乘除 4 種運算操作之一,用得到的結(jié)果取代選出的 2 個數(shù)字
# 先添加未選擇的數(shù)字
newNums = [z for k, z in enumerate(nums) if k not in (i, j)]
for k in range(4):
if k < 2 and i > j:
# 加法和乘法滿足交換律,跳過第二種順序
continue
if k == 3 and (round(y, 3) == 0):
# 除法運算除數(shù)不能為0
continue
v = ops[k](x, y)
newNums.append(v)
record.append(([round(x, 3), round(y, 3)],
op_char[k], round(v, 3)))
if solve(newNums):
return True
newNums.pop()
record.pop()
return False
flag = solve(nums)
if not flag:
return False, ""
cache = defaultdict(list)
for ns, op, v in record:
for i in range(2):
if cache[ns[i]]:
ns[i] = "("+cache[ns[i]].pop()+")"
a, b = ns
cache[v].append(f"{a}{op}")
return flag, cache[24][0]+"=24"
然后開始遍歷:
total = cnt = 0
for nums in combinations_with_replacement(range(1, 10), 4):
total += 1
r, expression = judgePoint24(nums)
if r:
print(expression, end="\t")
cnt += 1
if cnt % 8 == 0:
print()
print()
print(f'{cnt}/{total}={cnt/total:.2%}')
最終結(jié)果:

可以看到,我們已經(jīng)得到了404個24點的有效解表達式。
到此這篇關(guān)于Python實現(xiàn)快速計算24點游戲的示例代碼的文章就介紹到這了,更多相關(guān)Python計算24點游戲內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
PythonWeb項目Django部署在Ubuntu18.04騰訊云主機上
這篇文章主要介紹了PythonWeb項目Django部署在Ubuntu18.04騰訊云主機上的相關(guān)知識,本文通過代碼加文字說明的形式給大家介紹的非常詳細,具有一定的參考借鑒價值 ,需要的朋友可以參考下2019-04-04
django自帶的權(quán)限管理Permission用法說明
這篇文章主要介紹了django自帶的權(quán)限管理Permission用法說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-05-05
pandas如何使用列表和字典創(chuàng)建?Series
這篇文章主要介紹了pandas如何使用列表和字典創(chuàng)建?Series,pandas 是基于NumPy的一種工具,該工具是為解決數(shù)據(jù)分析任務(wù)而創(chuàng)建的,下文我們就來看看文章是怎樣介紹pandas,需要的朋友也可以參考一下2021-12-12
python實現(xiàn)對doc,txt,xls文檔的讀寫操作
這篇文章主要介紹了python實現(xiàn)對doc,txt,xls文檔的讀寫操作,正如標題所見,文章包括三個部分python實現(xiàn)對doc文檔的讀取、python實現(xiàn)對txt文檔的讀取和python實現(xiàn)對xls表格的讀取,需要的朋友可以參考一下2022-04-04

