一個(gè)24點(diǎn)游戲的算法壁榕,幫你深刻理解python中的匿名函數(shù)

首先簡(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')
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市恬口,隨后出現(xiàn)的幾起案子校读,更是在濱河造成了極大的恐慌,老刑警劉巖祖能,帶你破解...
    沈念sama閱讀 211,743評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件歉秫,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡芯杀,警方通過查閱死者的電腦和手機(jī)端考,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來揭厚,“玉大人却特,你說我怎么就攤上這事∩冈玻” “怎么了裂明?”我有些...
    開封第一講書人閱讀 157,285評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)太援。 經(jīng)常有香客問我闽晦,道長(zhǎng),這世上最難降的妖魔是什么提岔? 我笑而不...
    開封第一講書人閱讀 56,485評(píng)論 1 283
  • 正文 為了忘掉前任仙蛉,我火速辦了婚禮,結(jié)果婚禮上碱蒙,老公的妹妹穿的比我還像新娘荠瘪。我一直安慰自己,他們只是感情好赛惩,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評(píng)論 6 386
  • 文/花漫 我一把揭開白布哀墓。 她就那樣靜靜地躺著,像睡著了一般喷兼。 火紅的嫁衣襯著肌膚如雪篮绰。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,821評(píng)論 1 290
  • 那天季惯,我揣著相機(jī)與錄音吠各,去河邊找鬼臀突。 笑死,一個(gè)胖子當(dāng)著我的面吹牛走孽,可吹牛的內(nèi)容都是我干的惧辈。 我是一名探鬼主播,決...
    沈念sama閱讀 38,960評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼磕瓷,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了念逞?” 一聲冷哼從身側(cè)響起困食,我...
    開封第一講書人閱讀 37,719評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎翎承,沒想到半個(gè)月后硕盹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,186評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡叨咖,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評(píng)論 2 327
  • 正文 我和宋清朗相戀三年瘩例,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片甸各。...
    茶點(diǎn)故事閱讀 38,650評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡垛贤,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出趣倾,到底是詐尸還是另有隱情聘惦,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布儒恋,位于F島的核電站善绎,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏诫尽。R本人自食惡果不足惜禀酱,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望牧嫉。 院中可真熱鬧剂跟,春花似錦、人聲如沸驹止。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)臊恋。三九已至衣洁,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間抖仅,已是汗流浹背坊夫。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工砖第, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人环凿。 一個(gè)月前我還...
    沈念sama閱讀 46,370評(píng)論 2 360
  • 正文 我出身青樓梧兼,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親智听。 傳聞我的和親對(duì)象是個(gè)殘疾皇子羽杰,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容