codeforces April fool contest 2017
提示:这篇文章的主题是code-golf(即写出尽可能短的代码),使用的语言是Python 2。这篇文章含有cf April Fool contest 2017的剧透。
至于为什么cf3月底的比赛现在才更呢。。因为现在闲的蛋疼嘛,cc太水了早就ak了没事做>_>
注:文章中的submission是截止发表日期(2017.8.12)的,“rank1的Ruby/Python代码”也是指截止2017.8.12时的rank1。
A.Numbers Joke
这题真没什么好说的,oeis上有数列(A006753),然后打下来即可。
rank1的ruby党就是把数列编码成Unicode了。。
因为当成一个codegolf题的话这题太无聊了,所以我就没写了>_>
B.Kids' Riddle
题解:转成16进制看有几个0。第一次提交是这样的,一看就不是合格的codegolfer。
def f(i) : return i in ['4','6','8','9','0','a','b','d'] def g(i) : return i in ['8','b'] print sum([f(i)+g(i) for i in hex(int(raw_input()))])-1
注意那个-1是因为hex()的返回值中有"0x"这个前缀,而0对答案是有$1$的贡献的。
然后显然可以把i in ['4','6',...]改成i in "46...",这样就省了一堆字节。
print sum([(i in'46890abd')+(i in'8b')for i in hex(int(raw_input()))])-1
然后居然比ruby代码要短,当上了rank2。
rank1的python代码用了count函数,比我还是不知道高到哪去了。(下面的代码是我改进了一下rank1的。。现在我是rank1了>_>
print sum(["046889abbd".count(x)for x in hex(int(input()))])-1
C.INTERCALC
求数列最大值与最后一项的异或。
首先对于python来说,输入的数列长度是没必要的,就把它丢掉了。然后代码长这样:
input() print (lambda x:max(x)^x[len(x)-1])(map(int,raw_input().split()))
啊。。发现x[len(x)-1]可以简写为x[-1],就又省了几个字节:
input() print (lambda x:max(x)^x[-1])(map(int,raw_input().split()))
做完D题之后发现lambda是我自作多情了,最裸的写法就可以再省$10$个字节。。。
input();x=map(int,raw_input().split());print max(x)^x[-1]
行吧。。我还是naive了啊。。新手golfer也不容易啊。。。
D.Touchy-Feely Palindromes
将数字串转成Braille(盲文)之后是回文串。
print ["No","Yes"][(lambda x:min([x[i]+x[::-1][i]in["33","46","59","77","80","64","95","08"]for i in range(len(x))]))(raw_input())]
这段代码是什么意思呢,就是x的第i位和对称的那一位必须是这几个组合中的某一个。例如说x的某一位是8,那么其对称位必须是0,因为8和0在Braille中是镜像的关系。
那个["No","Yes"][]的trick是我思考了一会弄出来的。本来打算用三目运算符,但是python的三目是b if a else c长得要死就改成了[b,c][a]。
然后那个字符串列表好长啊。。于是改了一下
print["No","Yes"][(lambda x:min([x[i]+x[::-1][i]in"33 46 59 77 80 64 95 08".split()for i in range(len(x))]))(raw_input())]
这个字符串还可以改进。比如说59和95显然写成595也是没问题的还能少$1$个字节。
print["No","Yes"][(lambda x:min(["33.464.595.808.77".count(x[i]+x[::-1][i])for i in range(len(x))]))(raw_input())]
接下来要干掉那个for i in range(len(x))。range和len连用长成狗!作为python小白我就开始查文档,查stackoverflow。。终于查到一个enumerate语法,它的意思是枚举(i,x[i])这个pair。啊对了,x[::-1][i]有$10$个字节呢,为什么不改成x[-1-i]呢(x[-a]表示倒数第a位)。
print["No","Yes"][(lambda x:min(["33.464.595.808.77".count(b+x[-a-1])for a,b in enumerate(x)]))(raw_input())]
然后我发现lambda是多此一举。。x=raw_input();比(lambda x:)(raw_input())不知道短到哪里去了。顺便count也是我脑抽了,B题的rank1大佬用count是因为答案可能有$2$,而这里答案顶多是$1$。
x=raw_input();print["No","Yes"][min([b+x[-a-1]in"33.464.595.808.77"for a,b in enumerate(x)])]
这样就缩到小于100B了。
目前排名rank2,rank1的ruby大爷应该是无法超越的吧。他的写法是将x的每一位换成对应的镜像,再看等不等于其反串。python有对应的语法,但是反而更长了(需要包含string库,方法的名称也长成狗)。下面是rank1代码
s=gets.chomp puts s==s.reverse.tr('1234567890','##36947058')?:Yes: :No
对应的python代码
from string import * s=raw_input();print["No","Yes"][s.translate(maketrans("12465980","r_649508"))==s[::-1]]
E.Twisted Circuit
要么计算这个电路,要么把它打表打出来。我选择了后者。先写一个裸的。
import sys u=int(''.join(sys.stdin.read(9).split()),2) print int(u in [8,12,14,1,9,3,11,15])
表显然可以写的更短。
import sys u=int(''.join(sys.stdin.read(9).split()),2) print 56074>>u&1
接下来看读入能不能更短一点。试验发现cf上的换行符是'\n',就可以用replace了。再把读入嵌进输出就好。
import sys print 56074>>(int(sys.stdin.read(9).replace('\n',''),2))&1
一些小改动省了$3$字节。。
import sys print 56074>>int(sys.stdin.read().replace('\n',''),2)&1
然后没忍住看了一下rank2的python代码。。直接用input来读取数据(input()读一个数返回的就是这个数,不是字符串),妙,实在是妙。
I=input a,b,c,d=I(),I(),I(),I() print (a^b)&(c|d)^((b&c)|(a^d))
F.Crunching Numbers Just For You
这题要做两件事:一是排序,二是拖时间(用户要求程序运行时间为$1\mathtt{s}$到$2\mathtt{s}$之间)。
以下是第一发提交(就排到了rank3
print ' '.join(map(str,sorted(map(int,raw_input().split()[1:])))) a=1e7 while a:a-=1
然后发现了一个(某种意义上)不需要在str和int之间转来转去的方法,可以少$10$字节。轻松rank1。
print' '.join(sorted(raw_input().split()[1:],key=int)) a=1e7 while a:a-=1
G.BF Calculator
下面是考场代码,把结果一位一位输出。
cur = 0 def gao(x) : global cur if cur < x : print '+'*(x-cur) + '.' else : print '-'*(cur-x) + '.' cur = x s=eval(raw_input()) for i in str(s) : gao(ord(i))
缩了一下变成这样。话说python中,字符串*负数=空串,这为缩代码带来了极大便利。
c=0 for i in str(input()):x=ord(i);print'+'*(x-c)+'-'*(c-x)+'.';c=x
又想了想可以换一种做法。每次输出一个字符然后移到一个新的地方输出另一个。少用两个变量。
for i in str(input()):print'+'*ord(i)+'.>'
拿到了跟一堆人的并列rank2。rank1又是ruby。>_>
最后
战况:
题号 | A | B | C | D | E | F | G |
排名(全部) | 没做 | 2 | 并列第4 | 2 | 4 | 1 | 并列第2 |
排名(Python) | 没做 | 2 | 并列第1 | 1 | 3 | 1 | 并列第1 |
好无聊啊