I was wondering how this program knows if a number is prime or not. I understand that it checks for remainders to find even numbers to divide by but how does it know that a number has only 2 factors? I'm new to the concept of recursion so a explanation of the steps would be helpful thank you.
Code
def RecIsPrime(m):
"""Uses recursion to check if m is prime."""
def PrimeHelper(m, j):
"""Helper Function to iterate through all j less than m up to 1 to look for even divisors."""
if j == 1: # Assume 1 is a prime number even though it's debatable.
return True
else:
#do this task if both conditionals are true
#else break and return false.
return m % j != 0 and PrimeHelper(m, j - 1)
return PrimeHelper(m, m -1)
Source
https://github.com/hydrogeologist/LearningPython/blob/master/_recursion%20example%20in%20Python
Lines: 184 to 194
It checks whether there's any number from m - 1 down to 1 that divides m, it doesn't check just even numbers.
EG, for RecIsPrime(10)
you will have these nested functions call:
PrimeHelper(10, 9) = 10 % 9 != 0 and PrimeHelper(10, 8)
↪ PrimeHelper(10, 8) = 10 % 8 != 0 and PrimeHelper(10, 7)
↪ PrimeHelper(10, 7) = 10 % 7 != 0 and PrimeHelper(10, 6)
↪ PrimeHelper(10, 6) = 10 % 6 != 0 and PrimeHelper(10, 5)
↪ PrimeHelper(10, 5) = 10 % 5 != 0 == false
10 % 5 != 0
is false
, so the right hand side of the and
won't be evaulated. PrimeHelper(10, 5)
will return false
and doesn't continue the recursion.
In PrimeHelper(10, 6)
you get 10 % 6 != 0
to be true
, but we've just seen PrimeHelper(10, 5)
to be false
so this will return false as well, and so will all the other calls.
This code is a tail recursion case, ie it can be seen as a recursive way to perform iteration. Note that Python doesn't actually interpret it that way (which would be an optimisation), but it is still helpful to see it like that:
See how every recursive call of PrimeHelper
has the same value for m , but has a value for j that is one less compared to the value it had in the previous call.
So the code is comparable to this variant:
def RecIsPrime(m):
for j in range(m-1, 1, -1):
if m % j == 0:
return False
return m > 1
In this variant every iteration corresponds to a recursive call in the original code. Note that return False
breaks the chain, which is done by m % j != 0
in the original code, ie there it serves two purposes:
False
PrimeHelper
anymore It is important to note that the two variants do not behave the same way when you call RecIsPrime
with an argument of 1 or less. In those cases the recursive code can produce a "division by zero" error (when RecIsPrime(1)
) or recurse for ever (eg RecIsPrime(-1)
or any lesser value). This is a bug. To correct it change:
return PrimeHelper(m, m -1)
by
return m > 1 and PrimeHelper(m, m -1)
which also fixes the case for 1: it is more than just "debatable" whether 1 is prime or not: it is definitely not.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.