Reputation: 87
Found this on Codewars. The function takes two arguments A and B and returns the last digit of A^B. The code below passes the first two test cases, but won't pass the next ones.
def last_digit(n1, n2):
number = n1**n2
if number % 2 == 0:
return number % 10
elif number % 2 != 0:
return number % 10
Test.it("Example tests")
Test.assert_equals(last_digit(4, 1), 4)
Test.assert_equals(last_digit(4, 2), 6)
Test.assert_equals(last_digit(9, 7), 9)
Test.assert_equals(last_digit(10, 10 ** 10), 0)
Upvotes: 7
Views: 8631
Reputation: 20042
I know this post is old, but maybe someone will find this dictionary-based approach useful, too.
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 last_digit(n1, n2):
if n2 == 0:
return 1
else:
n1_last_digit = int(str(n1)[-1])
cycle = cycles[n1_last_digit]
return cycle[(n2 % 4) - 1]
Upvotes: 3
Reputation: 17263
Problem is easy to solve once you realize that the last digits of powers form a cycle. For example:
2: 2, 4, 8, 6, 2, 4
3: 3, 9, 7, 1, 3, 9
With that in mind you can create the cycle first and then just index it with modulo of n2
:
def last_digit(n1, n2):
if n2 == 0:
return 1
cycle = [n1 % 10]
while True:
nxt = (cycle[-1] * n1) % 10
if nxt == cycle[0]:
break
cycle.append(nxt)
return cycle[(n2 - 1) % len(cycle)]
This is also faster than using pow
:
def last_digit_pow(n1, n2):
return pow(n1, n2, 10)
if __name__ == '__main__':
import timeit
print(timeit.timeit("last_digit(10, 10 ** 10)", setup="from __main__ import last_digit"))
print(timeit.timeit("last_digit_pow(10, 10 ** 10)", setup="from __main__ import last_digit_pow"))
Output (Windows 8 & Python 2.7):
0.832171277335
4.08073167307
Output (Windows 8 & Python 3.5):
0.6951034093766606
1.9045515428013722
Output with 10**100
(Windows 8 & Python 3.5):
0.8367381690724996
10.928452962508006
Upvotes: 8
Reputation: 74645
Don't compute n1**n2
. The problem comes when you attempt to compute:
10**(10**10)
That is a 1 followed by ten billion zeroes.
Use pow(n1, n2, 10)
this makes the problem (more) tractable as it computes the exponentiation modulo 10
. Then as the number is already reduced modulo 10 the function can be rewritten as:
def last_digit(n1, n2):
return pow(n1, n2, 10)
Upvotes: 10