首先簡(jiǎn)單地介紹一下24點(diǎn)游戲:將一副撲克牌去除大小王矛紫,AK分別代表113。任意抽出4張牌里,任意使用加減乘除四則運(yùn)算颊咬,使得這四個(gè)數(shù)運(yùn)算的結(jié)果等于24。要求這四個(gè)數(shù)必須也只能使用一次牡辽。
聽上去很簡(jiǎn)單吧喳篇,下面我們就要運(yùn)用python中的匿名函數(shù)來實(shí)現(xiàn)這個(gè)算法,要求這個(gè)算法滿足:任意輸入4個(gè)數(shù)(例如:2,2,11,11)态辛,能夠返回一個(gè)四則運(yùn)算等式(就像這樣:((2/11)+2)*11=24)麸澜,如果不能算出,就告訴我們算不出來奏黑。
好啦炊邦,廢話不多說了,直接上代碼攀涵。( 注釋應(yīng)該很詳細(xì)了吧 ^_* )
# coding=utf-8
#!/usr/bin/python
class Numbers(object):
def __init__(self, numbers):
#初始化一個(gè)數(shù)組對(duì)象铣耘,這個(gè)對(duì)象包含四個(gè)待處理的數(shù)
self.numbers=numbers
#獲取輸入元素的所有組合
def combine(self,array,length):
arr=[]
if length==4:
for i in array:
for j in array:
for k in array:
for l in array:
arr.append([str(i),str(j),str(k),str(l)])
elif length==3:
for i in array:
for j in array:
for k in array:
arr.append([str(i),str(j),str(k)])
return(arr)
#調(diào)用judge函數(shù)去除不符合要求的組合,
#比如:原數(shù)組是2 2 3 4,那么要求生成的數(shù)組滿足:
#存在兩個(gè)2以故,一個(gè)3和一個(gè)4蜗细,不能多也不能少
def decrease(self,array):
arr=[]
for i in range(len(array)):
if self.judge(array[i]):
arr.append(array[i])
return(arr)
#對(duì)生成的數(shù)組進(jìn)行排序,判定是否和原數(shù)組相等怒详,
def judge(self,array):
tmp=sorted(array)
if self.numbers==tmp:
return(1)
return(0)
#根據(jù)加減乘除的符號(hào)返回對(duì)應(yīng)的運(yùn)算函數(shù)
#在python中炉媒,函數(shù)也能作為返回值
#這里使用了lambda來定義匿名函數(shù)
def fun(self,measure):
if measure=='+':
f=lambda x,y : x+y
elif measure=='-':
f=lambda x,y : x-y
elif measure=='*':
f=lambda x,y : x*y
elif measure=='/':
f=lambda x,y : x/y
else:
raise ValueError
return(f)
#結(jié)合數(shù)組中的四個(gè)數(shù)字和運(yùn)算法則,進(jìn)行運(yùn)算昆烁,判定結(jié)果是否等于24
def figure(self,numbers,measures):
#這是一個(gè)三層遞歸調(diào)用吊骤,每一層的fun函數(shù)返回的函數(shù)都可能不一樣,
#具體是什么取決于運(yùn)算符號(hào)measure
out=self.fun(measures[2])(
self.fun(measures[1])(
self.fun(measures[0])(
float(numbers[0])
,float(numbers[1]))
,float(numbers[2]))
,float(numbers[3]))
if out==24:
return(1)
else:
return(0)
#過濾掉數(shù)組中重復(fù)的部分
def screen(self,array):
#將array中重復(fù)的元素置空
for i in range(len(array)):
s=list(array)
s[i]=''
if(array[i] in s):
array[i]=''
#定義一個(gè)臨時(shí)數(shù)組tmp静尼,放入array中非空的元素
tmp=[]
for arr in array:
if arr!='':
tmp.append(arr)
return(tmp)
if __name__ == '__main__':
#獲取輸入的四個(gè)數(shù)
numbers=input('''
Please input 4 numbers to calculate,
these numbers are split by space ',' ';' and '-',
which just looks like "1 2 3 4" .\n''')
#支持的分割符都在這個(gè)數(shù)組里
char=[',',';','-','\n']
#對(duì)char里的字符進(jìn)行替換白粉,以空格來分割numbers传泊,
#得到包含所輸4個(gè)數(shù)字的數(shù)組numbers
#(這里似乎可以換個(gè)名字,不過本人習(xí)慣這么寫了)
for c in char:
numbers=numbers.replace(c,' ')
numbers=(numbers.split(' '))
#對(duì)輸入的數(shù)進(jìn)行排序
numbers.sort()
#給出一個(gè)Numbers對(duì)象的實(shí)例num并初始化
num=Numbers(numbers)
#先得到四個(gè)數(shù)字的所有排列組合鸭巴,再篩除那些不符合judge函數(shù)要求的組合
subnumbers=num.decrease(num.combine(numbers,4))
#定義包含加減乘除四個(gè)運(yùn)算符的數(shù)組measures
measures=['+','-','*','/']
#由于四則運(yùn)算可以有重復(fù)的運(yùn)算眷细,所以不需要調(diào)用decrease函數(shù)來進(jìn)行judge篩選
submeasures=num.combine(measures,3)
#定義一個(gè)數(shù)組arr來存放運(yùn)算結(jié)果等于24的數(shù)字和運(yùn)算符的組合
arr=[]
for i in range(len(subnumbers)):
for j in range(len(submeasures)):
#如果數(shù)字組合和四則運(yùn)算符號(hào)組合的運(yùn)算結(jié)果等于24,
#則把這兩對(duì)組合存放到arr數(shù)組中
if num.figure(subnumbers[i],submeasures[j]):
arr.append('Pass: ((%s%s%s)%s%s)%s%s=24' % (
subnumbers[i][0], submeasures[j][0], subnumbers[i][1],
submeasures[j][1], subnumbers[i][2], submeasures[j][2],
subnumbers[i][3]))
#舍棄arr中重復(fù)的元素
arr=num.screen(arr)
#將非空的組合打印到終端鹃祖,否則提示不能計(jì)算出
if arr!=[]:
for a in arr:
print(a)
else:
print('Sorry, this combination cannot be figured out.')
# 終于結(jié)束了溪椎,有收獲就點(diǎn)個(gè)贊吧 ^_^
print('Finished')