@sevenup233
2018-04-24T16:22:31.000000Z
字数 6342
阅读 664
CodeWar
20180403
题目:折叠函数float(a,n),例如float([1,2,3],1) = [4,2]
初见:
def fold_array(a, n):b = a[:]for i in range(n):for i in range(len(b)//2):b[i] += b[-i-1]b[:] = b[:(len(b)+1)//2]return(b)
亮点答案:
我觉得挺好的了
总结:
#list的深浅复制#浅复制只是表面功夫,牵一发而动全身a = [1,2,3]b = ab[0] = 2print(a,b)#都是[2,2,3]#深复制a = [1,2,3]b = a[:]b[0] = 2print(a,b)#a是[1,2,3]b是[2,2,3]
切片中负数是好东西,[:]是更好的东西。这题感受很多,题目本身并不难,折叠加法用个负数切片就能搞定,难点是测试程序会连续测试同一个list。最开始我直接对list修改,导致连续测试出现问题,让我想了很久,最后了解了深浅复制才得以解决。
所以不能把问题想得太简单,有时候你看得到的很容易,但你一下子没看到的就会要了你的命
20180405
题目:1^4 + 6^4 + 3^4 + 4^4 = 1 + 1296 + 81 + 256 = 1634,这样的返回bool Ture
初见:
def narcissistic(a):b = 0for i in str(a):b += int(i)**len(str(a))return(b==a)
亮点答案:
def narcissistic(a):return a == sum(int(i)**len(str(a)) for i in str(a))
总结:
bool类型还是挺方便的,最开始虽然想到但是没有想到直接用sum那么巧,多加了一个变量,注意缩进
20180406
题目:加密/解密
初见:
def encrypt(s, n):for i in range(n):s = s[1::2]+s[::2]return(s)def decrypt(s, n):if n <= 0:return(s)else:ss = str()for j in range(n):s1 = s[:len(s)//2]s2 = s[len(s)//2:]ss = str()for i in range(len(s1)):ss += s2[i]+s1[i]if len(s) % 2 != 0:ss+=s2[-1]s = ssreturn(ss)
亮点答案:
加密挺好的,解密都差不多
总结:那张纸写一下就找到规律了
20180407
题目:rgb(-100, 255, 300) returns 00FFFF
初见
def rgb(r, g, b):ans = ''for i in r,g,b:if i <= 0:ans += '00'elif i <= 15:ans += '0' + str.upper(hex(i)[-1:])elif i <= 255:ans += str.upper(hex(i)[2:])else:ans += 'FF'return(ans)
亮点答案:
def rgb(r, g, b):return ''.join(['%02X' % max(0, min(x, 255)) for x in [r, g, b]])
总结:
hex()变16进制、bin()变10、oct()变8,str.upper()加粗;join对于字符串添加还是很方便,format是很牛逼的格式化函数,格式化字符也很常用,比如%02X %10就是两位16进制大。早知道有格式化中间一大段判断和修饰就能全省了
print '%d'%10 # 输出十进制>> 10print '%o'%10 # 输出八进制>> 12print '%02x'%10 # 输出两位十六进制,字母小写空缺补零>> 0aprint '%04X'%10 # 输出四位十六进制,字母大写空缺补零>> 000A
20180408
题目:把秒换成具体时间,一堆格式要求
初见:
def format_duration(t):if t == 0:return('now')ans = []an = str()y = t//31536000d = (t%31536000)//86400h = ((t%31536000)%86400)//3600m = (((t%31536000)%86400)%3600)//60s = (((t%31536000)%86400)%3600)%60li = [('second',s),('minute',m),('hour',h),('day',d),('year',y)]for i,j in li:if j == 1:ans.append('%s %s'%(j,i))elif j >= 1:ans.append('%s %ss'%(j,i))for i,j in enumerate(ans):if i == 0:an += jelif i == 1:an = j + ' and ' + anelse:an = j + ', ' + anreturn(an)
亮点答案:
#最后用return join方法输出,比如这样,可以省一个完整的循环return ', '.join(chunks[:-1]) + ' and ' + chunks[-1] if len(chunks) > 1 else chunks[0]
总结:
难点在于输出要求的格式,两个循环都用在格式上了,基本上后面两个循环都跑不掉
20180409
题目:正则抓域名
初见:
import redef domain_name(url):a = re.search(r'([a-zA-Z]+://|[0-9a-zA-Z-_]+)\.([0-9a-zA-Z/-_]+)', url)for i in a.groups():if i != 'www':return(i)break
亮点答案:
def domain_name(url):return url.split("//")[-1].split("www.")[-1].split(".")[0]
总结:
正则这东西不好说,就是域名也有很多种情况出现,还是要特定情况分析,不过这个直接切还是牛逼
题目:判断括号升级版
初见:
#虽然测试过了但其实是错的,比如({[)]}def validBraces(a):b,c,d = 0,0,0for i in a:if i == '(':b += 1if i == ')':b -= 1if i == '[':c += 1if i == ']':c -= 1if i == '{':d += 1if i == '}':d -= 1if b<0 or c<0 or d<0:return Falsereturn b==0 and c==0 and d==0
亮点答案:
#用dict让左括号当键,右括号当值def validBraces(string):braces = {"(": ")", "[": "]", "{": "}"}stack = []for character in string:if character in braces.keys():stack.append(character)else:if len(stack) == 0 or braces[stack.pop()] != character:return Falsereturn len(stack) == 0#移除法,总有最小闭合括号,一层一层剥开你的心def validBraces(s):while '{}' in s or '()' in s or '[]' in s:s=s.replace('{}','')s=s.replace('[]','')s=s.replace('()','')return s==''
总结:
一开始想的很简单,他怎么说我怎么做,但是括号不只当做str,也可以当做计数工具
20180411
题目:数字变成罗马字符
初见:
def solution(a):ans=[]re = [['I','V','IV','IX'],['X','L','XL','XC'],['C','D','CD','CM']]b=[i for i in str(a)][::-1]for i,j in enumerate(b):if j == '9':ans.append(re[i][3])elif j == '4':ans.append(re[i][2])else:if i < 3:f = int(j)//5o = int(j)%5add = f*re[i][1] + o*re[i][0]ans.append(add)if i >= 3:ans.append(int(j)*'M')return ''.join(ans[::-1])
亮点答案:
def solution(n):return " M MM MMM".split(" ")[n//1000] + \" C CC CCC CD D DC DCC DCCC CM".split(" ")[n//100%10] + \" X XX XXX XL L LX LXX LXXX XC".split(" ")[n//10%10] + \" I II III IV V VI VII VIII IX".split(" ")[n%10]
总结:
原来可以把所有情况都列出再选。。。学到了,我是觉得这样太怂了还是用函数生成
20180415
题目:逆波兰式求值
初见:
def calc(a):if a == "":return 0else:b=a.split(' ')c=[]li=['+','-','*','/']for i in b:if i not in li:c.append(float(i))elif i in li:c.append(eval('%s%s%s'%(c.pop(-2),i,c.pop())))return(c[-1])
亮点答案:
def calc(expr):stack = [][stack.append(eval("{1}{2}{0}".format(stack.pop(), stack.pop(), e)) if e in ('+', '-', '/', '*') else e) for e in expr.split()]return float(stack.pop()) if stack else 0
总结:我的想法对于没有运算的情况字符串直接切会输出字符串,所以要用float,还是集成度不够高
20180416
题目:顺时针输出n*n表的数字
初见:
def snail(a):if len(a)<=1:return a[0]snail=[a[0][0]]i,j=1,1t=len(a)while len(snail)!=len(a)**2:if j<t:j += 1elif i<t:i += 1elif i==j==t:j -= 1t = len(a)-jelif j>t:j -= 1elif i>t+1:i -= 1elif i==j+1:j += 1t = len(a)-j+1snail.append(a[i-1][j-1])return(snail)
亮点答案:
#zip法def snail(array):return list(array[0]) + snail(list(zip(*array[1:]))[::-1]) if array else []def snail(array):a = []while array:a.extend(list(array.pop(0)))array = list(zip(*array))array.reverse()return a#拆迁法def snail(array):res = []while len(array) > 1:res = res + array.pop(0)res = res + [row.pop(-1) for row in array]res = res + list(reversed(array.pop(-1)))res = res + [row.pop(0) for row in array[::-1]]return res if not array else res + array[0]#旋转切割法,巨帅def snail(array):out = []while len(array):out += array.pop(0)array = list(zip(*array))[::-1]return out
总结:
看到别人写的答案后,第一感觉是我的智商收到了侮辱,我是想着转圈一个个加入,大神该拆的拆,该组装的组装。不过学到了zip在行列式中近乎无敌的旋转xy轴用法,牛逼。
20180419
题目:小键盘,每一个件都有可能是自己+四周的值,给一串按键,输出全部可能
初见:
def get_pins(a):re = [['0','8'],['1','2','4'],['2','1','3','5'],['3','2','6'],['4','1','5','7'],['5','2','4','6','8'],['6','3','5','9'],['7','4','8'],['8','5','7','9','0'],['9','6','8']]ans = [re[int(i)] for i in list(iter(a))]while len(ans)-1:ans[-1] = [j + i for i in ans.pop() for j in ans[-1]]return(ans[0])
亮点答案:
#引用product模块,很方便,如#product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dyfrom itertools import productADJACENTS = ('08', '124', '2135', '326', '4157', '52468', '6359', '748', '85790', '968')def get_pins(observed):return [''.join(p) for p in product(*(ADJACENTS[int(d)] for d in observed))]
总结:
经历了罗马字符的教训,学会提前准备一个表了,也学会用pop节约代码
20180422
题目:
初见:
#小范围可行from itertools import productmethod=len([sum(x) for x in product(*[range((k+1)*coin[i])[::coin[i]] for i,k in enumerate([money//j for j in coin if money//j>=0])]) if sum(x)==money])#优化后节省了内存from itertools import productdef count_change(money, coins):coins.sort()method=[range((k+1)*coins[i])[::coins[i]] for i,k in enumerate([money//j for j in coins if money//j>0])]while len(method)-1:method[-1]=[i+j for i in method.pop() for j in method[-1] if i+j<=money]method[0].count(money)return(method[0].count(money))
亮点答案:
#迭代法def count_change(money, coins):if money<0:return 0if money == 0:return 1if money>0 and not coins:return 0return count_change(money-coins[-1],coins) + count_change(money,coins[:-1])#牛逼法def count_change(money, coins):dp = [1]+[0]*moneyfor coin in coins:for x in xrange(coin,money+1):dp[x] += dp[x-coin]return dp[money]
总结:
一开始用循环来做发现要用到三层循环,虽然代码行数少但是内存炸了,想到要用迭代但是不知道怎么写,最终反复优化节约内存还是用循环强行做出来了。
迭代法思路清晰简单,但是牛逼法真的太牛逼了,看懂后佩服的五体投地