首先簡單地介紹一下24點游戲:將一副撲克牌去除大小王,AK分別代表113。任意抽出4張,任意使用加減乘除四則運算,使得這四個數(shù)運算的結(jié)果等于24。要求這四個數(shù)必須也只能使用一次。
聽上去很簡單吧,下面我們就要運用python中的匿名函數(shù)來實現(xiàn)這個算法,要求這個算法滿足:任意輸入4個數(shù)(例如:2,2,11,11),能夠返回一個四則運算等式(就像這樣:((2/11)+2)*11=24),如果不能算出,就告訴我們算不出來。
好啦,廢話不多說了,直接上代碼。( 注釋應(yīng)該很詳細(xì)了吧 ^_* )
# coding=utf-8
#!/usr/bin/python
class Numbers(object):
def __init__(self, numbers):
#初始化一個數(shù)組對象,這個對象包含四個待處理的數(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ù)組滿足:
#存在兩個2,一個3和一個4,不能多也不能少
def decrease(self,array):
arr=[]
for i in range(len(array)):
if self.judge(array[i]):
arr.append(array[i])
return(arr)
#對生成的數(shù)組進行排序,判定是否和原數(shù)組相等,
def judge(self,array):
tmp=sorted(array)
if self.numbers==tmp:
return(1)
return(0)
#根據(jù)加減乘除的符號返回對應(yīng)的運算函數(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ù)組中的四個數(shù)字和運算法則,進行運算,判定結(jié)果是否等于24
def figure(self,numbers,measures):
#這是一個三層遞歸調(diào)用,每一層的fun函數(shù)返回的函數(shù)都可能不一樣,
#具體是什么取決于運算符號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]=''
#定義一個臨時數(shù)組tmp,放入array中非空的元素
tmp=[]
for arr in array:
if arr!='':
tmp.append(arr)
return(tmp)
if __name__ == '__main__':
#獲取輸入的四個數(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''')
#支持的分割符都在這個數(shù)組里
char=[',',';','-','\n']
#對char里的字符進行替換,以空格來分割numbers,
#得到包含所輸4個數(shù)字的數(shù)組numbers
#(這里似乎可以換個名字,不過本人習(xí)慣這么寫了)
for c in char:
numbers=numbers.replace(c,' ')
numbers=(numbers.split(' '))
#對輸入的數(shù)進行排序
numbers.sort()
#給出一個Numbers對象的實例num并初始化
num=Numbers(numbers)
#先得到四個數(shù)字的所有排列組合,再篩除那些不符合judge函數(shù)要求的組合
subnumbers=num.decrease(num.combine(numbers,4))
#定義包含加減乘除四個運算符的數(shù)組measures
measures=['+','-','*','/']
#由于四則運算可以有重復(fù)的運算,所以不需要調(diào)用decrease函數(shù)來進行judge篩選
submeasures=num.combine(measures,3)
#定義一個數(shù)組arr來存放運算結(jié)果等于24的數(shù)字和運算符的組合
arr=[]
for i in range(len(subnumbers)):
for j in range(len(submeasures)):
#如果數(shù)字組合和四則運算符號組合的運算結(jié)果等于24,
#則把這兩對組合存放到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)
#將非空的組合打印到終端,否則提示不能計算出
if arr!=[]:
for a in arr:
print(a)
else:
print('Sorry, this combination cannot be figured out.')
# 終于結(jié)束了,有收獲就點個贊吧 ^_^
print('Finished')