Walkthrough of Text Holes Golf
Mar 16, 2022 python, CHECKIO冲分的时候又到了!!
题目要求
题目要求一如既往的简单明了:
统计一段文字中,有多少空格满足周围都不是空格字符的数量
而原始代码嘛……
def golf(text):
return 0
思路
我还是先用普通的方式来实现,然后再简化程序。 第一行、最后一行、第一列和最后一列不可能有满足条件的空格,所以在代码里面就直接忽略了。
def golf(t):
c = 0
for r in range(1, len(t) - 1):
for i in range(1, len(t[r]) - 1):
try:
if (t[r][i] == ' 'and t[r][i - 1] != ' 'and t[r][i + 1] != ' 'and t[r - 1][i] != ' 'and t[r + 1][i] != ' 'and t[r + 1][i+1] != ' 'and t[r-1][i-1] != ' 'and t[r + 1][i-1] != ' 'and t[r-1][i+1] != ' '):
c += 1
except:
pass
return c
当然,不出意外的。我们的代码太长了:
Your code is correct, but this is too long (414) for any points
简化
简单的将空格去掉后再测试,结果是:
Your code is correct, but this is too long (355) for any points
再把判断周围一圈的判断代码改成not in这样:
def golf(t):
c=0
for r in range(1,len(t)-1):
for i in range(1,len(t[r])-1):
try:
if t[r][i]==' 'and' 'not in[t[r][i-1],t[r][i+1],t[r-1][i],t[r+1][i],t[r+1][i+1],t[r-1][i-1],t[r+1][i-1],t[r-1][i+1]]:
c+=1
except:pass
return c
这样改动后,结果是:Points: 46, Place: 57th
虽然简化了很多,但是可以发现,代码太长主要是亮点:
- 两层for循环
- 判断语句太长
我们现在要想办法来简化这两个地方。首先想到的是能不能简化判断语句。如果我们每次取出一个3×3的方块,然后保证中间是空格,其他不是就可以了。也就是说,对于这样的一个方块
a='1fji "9br'
我们只要判断
a.count(' ')==1 and a[5]==' '
即可。这样相对原来的长度就短了很多。
第二部就是如何产生这个方块。我们假设如下的字符串
a="How are you doing?"
b="I'm fine. OK."
c="Lorem Ipsum?"
那么我们可以用如下的方法得到我们需要的东西:
a="How are you doing?"
b="I'm fine. OK."
c="Lorem Ipsum?"
[(a[i:i+3], b[i:i+3], c[i:i+3]) for i in range(0, min(len(a), len(b), len(c)))]
[('How', "I'm", 'Lor'),
('ow ', "'m ", 'ore'),
('w a', 'm f', 'rem'),
(' ar', ' fi', 'em '),
('are', 'fin', 'm I'),
('re ', 'ine', ' Ip'),
('e y', 'ne.', 'Ips'),
(' yo', 'e. ', 'psu'),
('you', '. O', 'sum'),
('ou ', ' OK', 'um?'),
('u d', 'OK.', 'm?'),
(' do', 'K.', '?')]
把上两个进行组合一下:
[1
for i in range(0, min(len(a), len(b), len(c)))
if b[i+1]==' ' and (a[i:i+3]+b[i:i+3]+c[i:i+3]).count(' ')==1]
有一个空格满足条件,这个我们可以手动进行验证。那么现在就是让a, b, c这三个变量能够变化起来。新的代码如下:
def golf(t):
c = 0
for j in range(0, len(t) - 2):
c+= sum([1
for i in range(0, min(len(t[j]), len(t[j + 1]), len(t[j + 2])) - 1)
if t[j + 1][i + 1] == ' ' and (t[j][i:i + 3] + t[j + 1][i:i + 3] + t[j + 2][i:i + 3]).count(' ') == 1 and len(t[j][i:i + 3] + t[j + 1][i:i + 3] + t[j + 2][i:i + 3])==9])
Personal best: 75, Place: 55th
再简化一点,同时把缩进改成1个空格:
def golf(t):
c=0
for j in range(0,len(t)-2):
x,y,z=t[j:j+3]
for i in range(0,min(len(x),len(y),len(z))-1):
u=x[i:i+3]+y[i:i+3]+z[i:i+3]
if y[i+1]==' 'and u.count(' ')==1 and len(u)==9:c+=1
return c
Personal best: 140, Place: 42nd
再小修改一下:
def golf(t):
c=0
for j in range(0,len(t)-2):
for i in range(0,min(map(len,t[j:j+3]))-1):
x,y,z=t[j:j+3];u=x[i:i+3]+y[i:i+3]+z[i:i+3]
if all([y[i+1]==' ',u.count(' ')*9==len(u)]):c+=1
return c
Personal best: 148, Place: 40th
虽然觉得还是有很大的提升空间,但是暂时想不出如何优化。暂时就此打住,以后有心的想法再修改。