python challenge level 10 url: http://www.pythonchallenge.com/pc/return/bull.html
pythonchallenge的第十题,真的是把我难住了阿,很轻易的从页面源代码中发现了所有信息,只需要根据sequence.txt这个文件中的序列找出第31个数字的长度就行了,这个数字的长度就是下一关的通行证。sequence.txt文件的内容如下:
a = [1, 11, 21, 1211, 111221,
我之前一直认为这是一组像小学初中高中所做的那种序列题目一样是一种拥有某种数学关系的序列,可是我错了,这一题并不是我想象中的递推数列,而是一种称为Look-and-say sequence的特殊数列。正是由于我这种固定的错误思维导致我并没有做出这一题,是在网上查到解答才知道这种数列。这种数列是使用后一个数来描述前一个数,例如sequence.txt文件中的5个数字:11描述前一个数1为1个1,21描述前一个数11为2个1,1211描述前一个数21为1个2,1个1,111221描述前一个数1211为1个1,1个2,2个1。根据这种规则一次类推,这样就可以找到第31个数,最后的到的结果是5808,下一题的链接为http://www.pythonchallenge.com/pc/return/5808.html。我的代码为:
#! /usr/bin/env python '''python challenge level 10 question url: http://www.pythonchallenge.com/pc/return/bull.html answer url: http://www.pythonchallenge.com/pcc/return/5808.html ''' a = '1' for i in xrange(30): pos = 0 tmp = '' str_len = len(a) while pos < str_len: count = 1 while pos + 1 < str_len and a[pos] == a[pos+1]: count += 1 pos += 1 tmp += '%d%s' % (count, a[pos]) pos += 1 a = tmp print len(a)
虽然这个数列的规律不是我自己发现的,不过这段代码是我自己写的。虽然也可以作为integer来完成不过使用string会比较方便。这里的代码属于C风格,在官方收集的答案中还有一些不错的解答方法,例如其中一个时使用正则表达式来解决的:
#! /usr/bin/env python x="1" for each in range(30): x="".join([str(len(i+j))+i for i,j in re.findall(r"(\d)(\1*)", x)]) print len(x)
这是官方的答案的链接:http://www.pythonchallenge.com/pcc/return/5808.html。
做完这道题之后,突然就觉得在前在一本叫《程序员的思维修炼》的书上看到的东西很对,自己太依赖于L型的思维,而乎略了R型的思维,如果自己打思维更开阔一些,在全局上多观察一下,利用一下别的感觉,例如朗读,通过各种各样的方法增强自己L、R的交互,其实这道题也不是那么难。以后有时间可以尝试一下书中介绍的增强两者联系的方法。