Codewars上有趣的题

最近一段时间常在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))))

  • 然后我往下翻,又看到了下面这个让我颇为震惊的解法:

    def digital_root(n):
        return n%9 or n and 9 
    我算了几个大于9的数,发现它们对9取余的结果确实是它们的数根,当时感觉这个结论很神奇,于是Google了一下之后,在知乎找到了相应的证明:https://www.zhihu.com/question/30972581 。而且这段代码中or和and的用法我也是头一次见,经过探索之后发现or和and在对数字使用的时候,大致遵循的规律是:

  • 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()输出一样的数,可以,很厉害。

  • 然后是这个:

    from random import randint
    class CheatingNumber:
        def __eq__(self, x):
            return True
    
    guess = CheatingNumber()
    前面那个强行改seed,你强行让 ‘ = ’ 运算符返回True????我服了。

  • 当然,最让我折服的还是下面这个:

    def randint(a, b):
        return 10
    guess = 10

    ?????????

    与上面这种解法类似的还有:

    randint,guess = lambda x,y:666,666

    哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈

Contents


本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。

知识共享许可协议