美文网首页程序员
一个24点游戏的算法,帮你深刻理解python中的匿名函数

一个24点游戏的算法,帮你深刻理解python中的匿名函数

作者: 天涯待归客 | 来源:发表于2016-12-09 13:33 被阅读753次

    首先简单地介绍一下24点游戏:将一副扑克牌去除大小王,AK分别代表113。任意抽出4张,任意使用加减乘除四则运算,使得这四个数运算的结果等于24。要求这四个数必须也只能使用一次。

    听上去很简单吧,下面我们就要运用python中的匿名函数来实现这个算法,要求这个算法满足:任意输入4个数(例如:2,2,11,11),能够返回一个四则运算等式(就像这样:((2/11)+2)*11=24),如果不能算出,就告诉我们算不出来。

    好啦,废话不多说了,直接上代码。( 注释应该很详细了吧 ^_* )

    # coding=utf-8
    #!/usr/bin/python
    
    class Numbers(object):
        def __init__(self, numbers):
            #初始化一个数组对象,这个对象包含四个待处理的数
            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)
    
        #调用judge函数去除不符合要求的组合,
        #比如:原数组是2 2 3 4,那么要求生成的数组满足:
        #存在两个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)
    
        #对生成的数组进行排序,判定是否和原数组相等,
        def judge(self,array):
            tmp=sorted(array)
            if self.numbers==tmp:
                return(1)
            return(0)
    
        #根据加减乘除的符号返回对应的运算函数
        #在python中,函数也能作为返回值
        #这里使用了lambda来定义匿名函数
        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)
    
        #结合数组中的四个数字和运算法则,进行运算,判定结果是否等于24
        def figure(self,numbers,measures):
            #这是一个三层递归调用,每一层的fun函数返回的函数都可能不一样,
            #具体是什么取决于运算符号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)
    
        #过滤掉数组中重复的部分
        def screen(self,array):
            #将array中重复的元素置空
            for i in range(len(array)):
                s=list(array)
                s[i]=''
                if(array[i] in s):
                    array[i]=''
            #定义一个临时数组tmp,放入array中非空的元素
            tmp=[]
            for arr in array:
                if arr!='':
                    tmp.append(arr)
            return(tmp)
    
    if __name__ == '__main__':
        #获取输入的四个数
        numbers=input('''
            Please input 4 numbers to calculate,
            these numbers are split by space ',' ';' and '-',
            which just looks like "1 2 3 4" .\n''')
        
        #支持的分割符都在这个数组里
        char=[',',';','-','\n']
        #对char里的字符进行替换,以空格来分割numbers,
        #得到包含所输4个数字的数组numbers
        #(这里似乎可以换个名字,不过本人习惯这么写了)
        for c in char:
            numbers=numbers.replace(c,' ')
        numbers=(numbers.split(' '))
    
        #对输入的数进行排序
        numbers.sort()
        #给出一个Numbers对象的实例num并初始化
        num=Numbers(numbers)
        #先得到四个数字的所有排列组合,再筛除那些不符合judge函数要求的组合
        subnumbers=num.decrease(num.combine(numbers,4))
    
        #定义包含加减乘除四个运算符的数组measures
        measures=['+','-','*','/']
        #由于四则运算可以有重复的运算,所以不需要调用decrease函数来进行judge筛选
        submeasures=num.combine(measures,3)
    
        #定义一个数组arr来存放运算结果等于24的数字和运算符的组合
        arr=[]
        for i in range(len(subnumbers)):
            for j in range(len(submeasures)):
                #如果数字组合和四则运算符号组合的运算结果等于24,
                #则把这两对组合存放到arr数组中
                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中重复的元素
        arr=num.screen(arr)
    
        #将非空的组合打印到终端,否则提示不能计算出
        if arr!=[]:
            for a in arr:
                print(a)
        else:
            print('Sorry, this combination cannot be figured out.')
        # 终于结束了,有收获就点个赞吧 ^_^
        print('Finished')
    

    相关文章

      网友评论

        本文标题:一个24点游戏的算法,帮你深刻理解python中的匿名函数

        本文链接:https://www.haomeiwen.com/subject/kamemttx.html