最近一段时间常在Codewars上刷题,也因而发现了几道有意思的题。
Sum of Digits / Digital Root
题目并不难,就是求数根(“數根是將一正整數的各個位數相加(即橫向相加),若加完後的值大於10的話,則繼續將各位數進行橫向相加直到其值小於十為止,或是,將一數字重複做數字和,直到其值小於十為止,則所得的值為該數的數根。” ——WIkipedia)。按照定义来做的话,也其实没什么难的,用python的话,无非就是分拆成字符,再转回数字然后相加,如此往复直到位数为1。然而在做完之后,我在Solutions里发现了这样两个答案:
-
首先是下面这个,巧妙地用了一下递归和map函数,使得代码短了很多;
def digital_root(n): return n if n < 10 else digital_root(sum(map(int,str(n))))
-
然后我往下翻,又看到了下面这个让我颇为震惊的解法:
我算了几个大于9的数,发现它们对9取余的结果确实是它们的数根,当时感觉这个结论很神奇,于是Google了一下之后,在知乎找到了相应的证明:https://www.zhihu.com/question/30972581 。而且这段代码中or和and的用法我也是头一次见,经过探索之后发现or和and在对数字使用的时候,大致遵循的规律是:def digital_root(n): return n%9 or n and 9
-
a and b,ab都非零时,结果为b;ab其中一个为0时,结果为0;
-
a or b,ab都非零时,结果为a;ab其中一个为0时,结果为另一个非零的数;
并且,0 and 0和0 or 0都等于0。另外就是and的运算级要高于or,所以return后面的执行顺序就是先and后or:
n != 0且n != 9时,n and 9 == 9,n % 9 or 9 == n % 9;
n == 0时,n and 9 == 0,n % 9 or 0 == 0;
n == 9时,n and 9 == 9,n%9 or 9 == 9;
Don’t rely on luck.
这题乍一看,感觉毫无技术含量可言,纯粹是看运气,他用randint从1到100随机抽一个数出来,让你也猜一个数,两数相等即可通过。
- 在代码框里最开始给的是:
from random import randint guess =
我想了一会儿,好像也没什么别的办法,就在guess后面填了个42,然后一遍遍地提交,在提交了许多许多许多次之后,终于对面random出了42,于是过了。过了之后当然要看看别人是怎么解的,在看了几个答案之后,我笑了很久……
-
首先是:
from random import randint,seed seed(1) guess = randint(1,100) seed(1)
强行改seed让randint()输出一样的数,可以,很厉害。
-
然后是这个:
前面那个强行改seed,你强行让 ‘ = ’ 运算符返回True????我服了。from random import randint class CheatingNumber: def __eq__(self, x): return True guess = CheatingNumber()
-
当然,最让我折服的还是下面这个:
def randint(a, b): return 10 guess = 10
?????????
与上面这种解法类似的还有:
randint,guess = lambda x,y:666,666
哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈