简体   繁体   English

求大功率的单位数

[英]Finding unit digit of large powers

I need to find the last digit of large power. 我需要找到大功率的最后一位。 When I get simple x^n, I solve problem with this: pow(x, n, 10). 当我得到简单的x ^ n时,我用以下方法解决了问题:pow(x,n,10)。 But what should I do when I have such example: 103171^(14394^(221515^(441792^507709)))? 但是当我有这样的示例时该怎么办:103171 ^(14394 ^(221515 ^(441792 ^ 507709)))? I noticed the cyclicity of specific digits, but it's not enough. 我注意到特定数字的周期性,但这还不够。 I am afraid I'm missing some important point. 恐怕我缺少一些要点。 As an input of my main function last_digit I get list of numbers (lst), let's say [3, 4, 2]- this means I need to compute 3 ^ (4 ^ 2). 作为主函数last_digit的输入,我得到数字列表(lst),比如说[3,4,2]-这意味着我需要计算3 ^(4 ^ 2)。 I've got about 630 tests to pass and I can only make about 580 (most of them are randomly generated). 我要通过大约630个测试,而我只能进行大约580个测试(其中大多数是随机生成的)。 Here's my code I've tried: 这是我尝试过的代码:

CYCLES = {
    0 : [0, 0, 0, 0],
    1 : [1, 1, 1, 1],
    2 : [2, 4, 8, 6],
    3 : [3, 9, 7, 1],
    4 : [4, 6, 4, 6],
    5 : [5, 5, 5, 5],
    6 : [6, 6, 6, 6],
    7 : [7, 9, 3, 1],
    8 : [8, 4, 2, 6],
    9 : [9, 1, 9, 1]
}

def power_rec(lst):
    remainder = pow(lst[-2], lst[-1], 4)
    if len(lst) == 2:
        first_num = int(str(lst[0])[-1])
        second_num = int(str(lst[1])[-1]) 
        return CYCLES[first_num][second_num - 1]
    lst = lst[:-2] + [ remainder ]
    return power_rec(lst)

def last_digit(lst):
    if len(lst) == 2:
        return pow(lst[0], lst[1], 10)
    if lst == []:
        return 1
    if len(lst) == 1:
        return int(str(lst[0])[-1])
    return power_rec(lst)

Eg I cannot pass tests with inputs: [555913, 845991, 261716, 431426, 571315, 456986, 461380, 413475] or [2, 2, 101, 2]. 例如,我无法通过输入[555913、845991、261716、431426、571315、456986、461380、413475]或[2、2、101、2]通过测试。

I have to assume that 0 ^ 0 = 1 and that last_digit of an empty list equals to 1. I'd appreciate any helpful tips. 我必须假设0 ^ 0 = 1,并且空列表的last_digit等于1。我会感谢任何有用的提示。

UPDATE. UPDATE。 Found shortest solution: 找到最短的解决方案:

def last_digit(lst):
    result = 1
    for num in lst[::-1]:
        result = pow(num, (result if result < 4 else result % 4 + 4) )

    return result % 10

This is a pure math problem... 这是一个纯粹的数学问题...

The last digit of any number is just that number modulo 10. So you are asking how to reduce numbers modulo 10 when they are a big cascade of exponents. 任何数字的最后一位数字都是该模10的数字。因此,您要问当它们是指数级数时如何减少10模的数字。

To do this, you can apply Euler's Theorem repeatedly. 为此,您可以重复应用欧拉定理 What it says (well, implies) is that to reduce a^b modulo n, you can reduce b modulo phi(n). 它的意思(暗示)是要减少a ^ b模n,您可以减少b模phi(n)。

So, to reduce a^b modulo 10, you can start by reducing b modulo phi(10) = 4. 因此,要降低a ^ b模数10,可以先降低b模数phi(10)= 4。

Here, b has the form c^d. 在此,b的形式为c ^ d。 To reduce c^d modulo 4, you can start by reducing d modulo phi(4) = 2. That's far enough to make this problem easy. 要减少c ^ d模4,您可以从减少d模phi(4)= 2开始。这足以使这个问题变得容易。

Let's take your example: 让我们举个例子:

103171^(14394^(221515^(441792^507709))) modulo 10 103171 ^(14394 ^(221515 ^(441792 ^ 507709)))模10

Start by reducing (221515^(blahblah)) modulo 2. That's pretty clearly 1, so we are already down to: 首先减少(221515 ^(blahblah))模2。这很明显是1,所以我们已经到了:

103171^(14394^1) = 103171^14394 modulo 10 103171 ^(14394 ^ 1)= 103171 ^ 14394模10

Next, just reduce 14394 modulo 4 to get 2. So we are down to: 接下来,只需将14394模4减少为2。因此,我们得出以下结论:

103171^2 modulo 10 103171 ^ 2模10

I think you can take it from there. 我想你可以从那里拿走。

(Update) (更新)

I forgot that Euler's theorem only applies when a (the base) and n (the modulus) have no factors in common. 我忘记了欧拉定理仅在a(基数)和n(模数)没有共同因素的情况下适用。 Whoops. 哎呦。

So when trying to reduce 14394^(blahblah) modulo 4, we have to do it directly... 14394^(large power) is actually divisible by 4, so this is actually zero and the correct answer is 103171^0 = 1. (Which the other approach also gave but just by luck.) 因此,当尝试减少14394 ^(blahblah)模4时,我们必须直接进行操作... 14394 ^(large power)实际上可以被4整除,因此实际上为零 ,正确的答案是103171 ^ 0 = 1。 (虽然这是另一种方法,但只是运气。)

For the example in your comment (7^(6^21)), we have a similar case. 对于您评论中的示例(7 ^(6 ^ 21)),我们有一个类似的情况。 6^21 is zero (mod 4), so the answer is 7^0 = 1. 6 ^ 21为零(模4),因此答案为7 ^ 0 = 1。

12^(30^21) it is even trickier because 12 and 10 are not relatively prime. 12 ^(30 ^ 21)甚至更棘手,因为12和10不是相对质数。 Here we will need to compute the value (mod 5) and (mod 2) and combine the two. 在这里,我们将需要计算值(mod 5)和(mod 2)并将两者结合起来。 But I am late for a meeting so I cannot finish this now :-) 但是我开会迟到了,所以我现在不能完成这件事:-)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM