codewar上面的一道题目:
给任意一个自然数,将各位上的数字加起来,如果得到一个大于一位数的结果,则再计算,知道得到一个一位数,那么这个一位数就是这个数的树根。利用代码求一个自然数的树根。
正常的思维代码如下:
def digital_root(n):
digital_sum = sum([int(i) for i in list(str(n))])
if len(str(digital_sum)) == 1:
return digital_sum
return digital_root(digital_sum)
以上是最起码的解法,但是这里面还有一个最优的解法,涉及到了九余数原理(如下):
(1)两个或多个数的加减乘除得到的结果的数根,等于对应各个数的数根的加减乘除的结果的树根。
(2)一个数的数根(特殊情况,如果数根为9,按0算)等于该数对9取余的结果。
具体的证明可以用一个等式:
X = 100*a + 10*b + c = 99*a + 9*b + (a+b+c)
上面的等式可以看出,任意一个数的树根等于对9的余数。
那么上面的代码就可以简化如下:
def digital_root(n):
return n%9 or n and 9
就是直接返回对9的余数就行了,但是要具体处理下99,999等情况,所有利用and函数进行返回。