@sevenup233
2018-04-24T16:22:31.000000Z
字数 6342
阅读 619
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 = a
b[0] = 2
print(a,b)
#都是[2,2,3]
#深复制
a = [1,2,3]
b = a[:]
b[0] = 2
print(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 = 0
for 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 = ss
return(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 # 输出十进制
>> 10
print '%o'%10 # 输出八进制
>> 12
print '%02x'%10 # 输出两位十六进制,字母小写空缺补零
>> 0a
print '%04X'%10 # 输出四位十六进制,字母大写空缺补零
>> 000A
20180408
题目:把秒换成具体时间,一堆格式要求
初见:
def format_duration(t):
if t == 0:
return('now')
ans = []
an = str()
y = t//31536000
d = (t%31536000)//86400
h = ((t%31536000)%86400)//3600
m = (((t%31536000)%86400)%3600)//60
s = (((t%31536000)%86400)%3600)%60
li = [('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 += j
elif i == 1:
an = j + ' and ' + an
else:
an = j + ', ' + an
return(an)
亮点答案:
#最后用return join方法输出,比如这样,可以省一个完整的循环
return ', '.join(chunks[:-1]) + ' and ' + chunks[-1] if len(chunks) > 1 else chunks[0]
总结:
难点在于输出要求的格式,两个循环都用在格式上了,基本上后面两个循环都跑不掉
20180409
题目:正则抓域名
初见:
import re
def 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,0
for i in a:
if i == '(':
b += 1
if i == ')':
b -= 1
if i == '[':
c += 1
if i == ']':
c -= 1
if i == '{':
d += 1
if i == '}':
d -= 1
if b<0 or c<0 or d<0:
return False
return 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 False
return 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)//5
o = int(j)%5
add = 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 0
else:
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,1
t=len(a)
while len(snail)!=len(a)**2:
if j<t:
j += 1
elif i<t:
i += 1
elif i==j==t:
j -= 1
t = len(a)-j
elif j>t:
j -= 1
elif i>t+1:
i -= 1
elif i==j+1:
j += 1
t = len(a)-j+1
snail.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 Dy
from itertools import product
ADJACENTS = ('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 product
method=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 product
def 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 0
if money == 0:
return 1
if money>0 and not coins:
return 0
return count_change(money-coins[-1],coins) + count_change(money,coins[:-1])
#牛逼法
def count_change(money, coins):
dp = [1]+[0]*money
for coin in coins:
for x in xrange(coin,money+1):
dp[x] += dp[x-coin]
return dp[money]
总结:
一开始用循环来做发现要用到三层循环,虽然代码行数少但是内存炸了,想到要用迭代但是不知道怎么写,最终反复优化节约内存还是用循环强行做出来了。
迭代法思路清晰简单,但是牛逼法真的太牛逼了,看懂后佩服的五体投地