zoukankan      html  css  js  c++  java
  • 一个貌似比较吊的递归转换为loop--总算成功了.

    class Stack(object):
        """
        A class to hold arguements and state data.
        """
        def __init__(self,**kwargs):
            self.__dict__.update(kwargs)
    
        def __repr__(self):
            extra = "|i:%s"%self.i if hasattr(self,'i') else ''
            return "n:%s|stage:%s%s"%(self.n,self.stage,extra)
        
    def memory(function):
        """
        A decorator to help a no-side-effect function avoid
        repeative calculation.
        """
        cache = {}
        def memofunc(*nkw,**kw):
            key=str(nkw)+str(kw)
            if key not in cache:            
                cache[key] = function(*nkw,**kw)
            return cache[key]
        return memofunc
    
    def is_equal(rg,*funclist):
        """
        to test whether or not a list of one-arguement functions
        have the same output if given same arguement.
        """
        for n in rg:
            rst=[]
            for func in funclist:
                rst.append(func(n))
                assert len(set(rst))==1
    
    @memory
    def hanoi_recur(n):
        """
        n -> (i,v)
        a recursive function to get the smallest number i
        and correspondent value.
        """
        if n==1:
            return 1,1
        psb=[]
        for i in range(n-1,0,-1):
            _, min_v = hanoi_recur(n-i)
            psb_v = 2*min_v+2**i-1
            psb.append((i,psb_v))
        return min(psb,key=lambda x:x[1])
    
    @memory
    def hanoi_loop(n):
        """
        The loop version of hanoi_recur.
        """
        if n==1:
            return 1,1
        stack = [Stack(n=n,stage=0,)]
        cache={1:1} 
        while stack:
            crt=stack.pop()    
            if crt.n in cache:
                psb_v = 2*cache[crt.n]+2**crt.i-1
                crt.prt.psb.append((crt.i,psb_v))
                continue
            if crt.stage==0: 
                crt.stage, crt.pgs, crt.psb= 1, 0, []
                stack.append(crt)
                continue
            if crt.stage==1:
                if crt.pgs != crt.n - 1:
                    crt.pgs += 1
                    stack.append(crt)
                    chd = Stack(n=crt.pgs, stage=0, i=crt.n-crt.pgs, prt=crt)
                    stack.append(chd)
                else:
                    crt.stage=2
                    stack.append(crt)
                continue
            if crt.stage==2 and hasattr(crt,'prt'):
                #hasattr - the last stack doesn't have attribute 'prt',
                #so it has to be excluded here.
                _, min_v = min(crt.psb,key=lambda x:x[1])            
                psb_v = 2*min_v + 2**crt.i - 1
                crt.prt.psb.append((crt.i,psb_v))
                cache[crt.n] = min_v
                continue
        return min(crt.psb,key=lambda x:x[1])
    
                
    if __name__=='__main__':
        is_equal(range(1,300),hanoi_loop,hanoi_recur)
        print('passed test!')
  • 相关阅读:
    Android -- 保存文件
    Android -- AsyncTask
    Java 集合
    Android -- ViewPager放入多个XML监听每个的控件
    Android -- 自定义标题栏,背景颜色填充满
    PowerShell正则表达式(一) 定义模式
    PowerShell 简单模式识别 1
    Powershell 设置数值格式 1
    PowerShell String对象方法 1
    PowerShell 字符串操作符
  • 原文地址:https://www.cnblogs.com/xiangnan/p/3572654.html
Copyright © 2011-2022 走看看