一个貌似比较吊的递归转换为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!')
一个貌似比较吊的递归转换为loop--总算成功了.的更多相关文章
- 一个貌似比较吊的递归转换为loop--总算成功了.--第二弹
前段时间用类似于散弹式编程的方式,各种猜测-运行验证-修正结果,最终成功转换了一个看起来比较有难度的递归函数.但总觉得很蛋疼,原因如下: 1.虽然正确,但是逻辑搞得比较复杂.现在去看,一头雾水,不知道 ...
- 将树形递归转换为loop
class Stack(object): def __init__(self,**kwargs): self.__dict__.update(kwargs) def __str__(self): re ...
- 记住经典的斐波拉契递归和阶乘递归转换为while规律
记住经典的斐波拉契递归和阶乘递归转换为while规律.它为实现更复杂转换提供了启发性思路. # 斐波拉契--树形递归 def fab(n): if n<3: return n return fa ...
- 一个超复杂的间接递归——C语言初学者代码中的常见错误与瑕疵(6)
问题: 问题出处见 C语言初学者代码中的常见错误与瑕疵(5) . 在该文的最后,曾提到完成的代码还有进一步改进的余地.本文完成了这个改进.所以本文讨论的并不是初学者代码中的常见错误与瑕疵,而是对我自己 ...
- 求一个集合S中m个元素的所有排列以及一个数组A的全排列—递归实现版完整代码
说明,本文全文代码均用dart语言实现. 求一个集合S中m个元素的所有排列情况,并打印,非常适合用递归的思路实现.本文给出了两种实现方法,一种是给定的填充排列数组长度是固定的,一种是可变长度的.两种方 ...
- 驳 GarbageMan 的《一个超复杂的简介递归》——对延迟计算的实验和思考
这是一篇因骂战而起的博文,GarbageMan 在该文章回复中不仅对我进行了侮辱,还涉及了我的母校,特写此文用理性的分析和实验予以回击. 在此也劝告 GarbageMan,没什么本事就别在那叫嚣了,还 ...
- 不规则递归转换为while,留底
我发现当参数并不太多时,从性能的角度来看,没必要用一个class来保存参数(虽然看起来更加生动形象),直接用最简单的元组就可以了. from hanoi import * # example tree ...
- 在主函数中提示用户输入用户名和密码。另写一方法来判断用户输入是否正确。该方法分别返回一个bool类型的登录结果和和一个string类型的登录信息。如登录成功,返回true及“登录成功”,若登录失败则返回false及“用户名错误”或“密码错误”(使用out参数)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- shell脚本安装python、pip--这种写法是错误的---每一个命令执行完都要判断是否执行成功,否则无法进行下一步
shell脚本安装python.pip--不需要选择安装项目--不管用总报错,必须带上判断符号,while没有这种用法,写在这里为了以后少走弯路,所以不要用下面的执行了 首先把pip-.tgz 安装包 ...
随机推荐
- Java面试题—初级(7)
作为一枚Java后端开发者,数据库知识必不可少,对数据库的掌握熟悉度的考察也是对这个人是否有扎实基本功的考察.特别对于初级开发者,面试可能不会去问框架相关知识,但是绝对不会不去考察数据库知识,这里收集 ...
- “百度杯”CTF比赛 九月场_YeserCMS
题目在i春秋ctf大本营 题目的提示并没有什么卵用,打开链接发现其实是easycms,百度可以查到许多通用漏洞 这里我利用的是无限报错注入 访问url/celive/live/header.php,直 ...
- [测试题]gentree
Description 给你一个有向连通图G,每点有个权值Di(0<Di),要求生成一棵树根为1号节点的有根树T.对于树中边E,E的代价为所有从根出发的且包含E的路径的终点权值的和.现求生成树T ...
- [Luogu 3389]【模板】高斯消元法
Description 给定一个线性方程组,对其求解 Input 第一行,一个正整数 n 第二至 n+1 行,每行 n+1 个整数,为a1,a2⋯an和 b,代表一组方程.1,a2⋯an ...
- [HAOI2008]圆上的整点
题目描述 求一个给定的圆(x^2+y^2=r^2),在圆周上有多少个点的坐标是整数. 输入输出格式 输入格式: r 输出格式: 整点个数 输入输出样例 输入样例#1: 4 输出样例#1: 4 说明 n ...
- WISCO信息组NOIP模拟赛-部落冲突
传送门 首先肯定考虑树剖,这里没有要求区间加,所以可以用树状数组维护,不会卡常的 这里是边权,可以转化为点权:让每条边连接的较深的节点的点权等于边权即可,然后计算的时候减去lca #include&l ...
- 【tyvj】刷题记录(1001~1099)(64/99)
1001:排序完按照题意做即可. #include<cstdio> #include<iostream> #include<cmath> #include<a ...
- hdu4549(费马小定理 + 快速幂)
M斐波那契数列F[n]是一种整数数列,它的定义如下: F[0] = a F[1] = b F[n] = F[n-1] * F[n-2] ( n > 1 ) 现在给出a, b, n,你能求出F[n ...
- hdu 5465 (树状数组 + 博弈)
题意:基于矩阵的NIM游戏,求异或和. 思路:在x1,y1 到 x2, y2的异或和 = A[ x2 ][ y2 ] ^ A[x1-1][ y2 ] ^ A[ x2 ][y1 - 1] ^ A[ x ...
- bzoj3944Sum
3944: Sum Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 5149 Solved: 1385[Submit][Status][Discuss ...