What is the recursive call (or inductive steps) for a function that returns the number of integers from 1 to N, which evenly divide N. The idea is to concieve a pure recursive code in python for this function. No 'for' or 'while' loops, neither modules can be used. The function num_of_divisors(42) returns 8, representing 1, 2, 3, 6, 7, 14, 21, and 42 as divisors of 42.
-
have you tried something already? – Joran Beasley Sep 30 '15 at 22:51
-
What is the point of the restrictions? Is this a curiosity or an academic assignment? – Robᵩ Sep 30 '15 at 22:51
-
2@Robᵩ you can always tell it's an academic assignment when a user asks a question using all the most detailed terminology ("recursive call or inductive steps for a function that returns the number of integers..." instead of "I need a recursive function that returns how many numbers...) – Adam Smith Sep 30 '15 at 22:52
-
I'm working on a series of postulates re. analytic number theory. Not seeking an efficient code. This instruction is to simply implement aliquot sum, exactly how the postulate states:num_of_divisor(12) = 1^0 + 2^0 + 3^0 + 4^0 + 6^0 + 12^0, which translates into: = 1 + 1 + 1 + 1 + 1 + 1 = 6. It may sound stupid, and I know that. And I also accept critics, but at this point I'm obssessed to find it... – HandyFrank Oct 01 '15 at 08:44
-
1) fully factor the number (this can be, but need not be, recursive), 2) calculate all possible combinations of the prime factors (could also be recursive), 3) eliminate duplicates if necessary. Alternatively, just iterate from 1 to N, testing for divisibility with the modulo operator. The first approach will be better for very large numbers, but where the cut-off is depends on the specific implementation... – twalberg Oct 01 '15 at 16:00
5 Answers
def num_of_divisors(n):
return sum(1 if n % i==0 else 0 for i in range(((n+1)**0.5)//1)
Good luck explaining it to your teacher!
If you really can't use for
loops (?????????) then this is impossible without simulating one.
def stupid_num_of_divisors_assigned_by_shortsighted_teacher(n, loop_num=1):
"""I had to copy this from Stack Overflow because it's such an
inane restriction it's actually harmful to learning the language
"""
if loop_num <= (n+1) ** 0.5:
if n % loop_num == 0:
return 2 + \
stupid_num_of_divisors_assigned_by_shortsighted_teacher(n, loop_num+1)
else:
return stupid_num_of_divisors_assigned_by_shortsighted_teacher(n, loop_num+1)
else:
if n % loop_num == 0:
return 1
Bonus points: explain why you're adding 2
in the first conditional, but only 1
in the second conditional!

- 52,157
- 12
- 73
- 112
-
1
-
@JoranBeasley I actually missed that. That's ridiculous. Anyway, updated so it fits the spirit of the assignment. – Adam Smith Sep 30 '15 at 23:02
-
i really hope he does what we assume people do with these answers alot of times (ie they dont use them to learn :P) – Joran Beasley Sep 30 '15 at 23:07
-
@JoranBeasley honestly it's impossible to learn from an assignment like this. You'd never ever ever ever ever ever ever EVER write a solution to this without using loops. It's ridiculous to request it. This kind of work is great for in-class brain teasers right after teaching loops and before introducing recursion. – Adam Smith Sep 30 '15 at 23:09
-
No doubts! Great code and I can do that one, just like it! However, this is part of my studies on theory of computer science, related to analytic number theory. Not seeking an efficient code. This instruction is to simply implement aliquot sum, exactly how the postulate states:num_of_divisor(12) = 1^0 + 2^0 + 3^0 + 4^0 + 6^0 + 12^0, which translates into: = 1 + 1 + 1 + 1 + 1 + 1 = 6. It may sound stupid, and I know that. And I also accept critics, but at this point I'm obssessed to find it... Thanks! – HandyFrank Oct 01 '15 at 08:46
-
...and btw. I agree. It's a ridiculous proposition. But come on, this is pure mathematics, and simple one! It's just a matter of implementing an equation! I got short on my python "grammar", but if recursion allowed evolution to accomplish what it has, we can do this! – HandyFrank Oct 01 '15 at 09:17
Here you go buddy your teacher'll be happy.
def _num_of_divisors(n, k):
if (k == 0):
return 0
return _num_of_divisors(n, k-1) + (n % k == 0)
def num_of_divisors(n):
return _num_of_divisors(n, n)

- 1,045
- 5
- 12
-
Two inputs. (n, k). The only input is N - or (n). This instruction is to simply implement aliquot sum, exactly how the postulate states:num_of_divisor(12) = 1^0 + 2^0 + 3^0 + 4^0 + 6^0 + 12^0, which translates into: = 1 + 1 + 1 + 1 + 1 + 1 = 6. Thanks! – HandyFrank Oct 01 '15 at 08:48
def n_divisors(n,t=1):
return (not n%t)+(n_divisors(n,t+1) if t < n else 0)
good luck on the test later ... better hit those books for real, go to class and take notes...
with just one input i guess
t=0
def n_divisors(n):
global t
t += 1
return (not n%t)+(n_divisors(n) if t < n else 0)

- 110,522
- 12
- 160
- 179
-
1Oh you can do better than that! Checking all t in (n+1)/2 is sufficient – Adam Smith Sep 30 '15 at 23:05
-
oh i know ... but meh I had that originally ... but then i figured i would leave him at least something to improve upon if he took it upon himself (plus i didnt have to make a special case to add the number its self :P) – Joran Beasley Sep 30 '15 at 23:06
-
yes, it's hard to hold back yourself, even if you know it's someone elses assignment. It was hard for me when i wrote my solution too :-) – cg909 Sep 30 '15 at 23:10
-
No doubts! Great code! i havent' thought anything like that except more than one input. Breach!! num_of_divisor(N) takes ONLY one input. Check the postulate above...Thanks! – HandyFrank Oct 01 '15 at 08:55
-
This is how the grader has told me it's incorrect:Traceback (most recent call last): File "test_file.py", line 12, in testNumDivisors2 self.assertEqual(hw.numDivisors(2), 2) AssertionError: 1 != 2 ...I believe global is a module! Arghhh!!! – HandyFrank Oct 01 '15 at 17:58
-
no its telling you it expects 1 and got 2 or it expected 2 and got 1... apparently it only expects one divisor for 2(but this code is correctly printing 2, instead of the expected 1) .... not sure how since every number by definition is divisble by itself and 1 ... how are you planning on actually passing this class? this is probably one of the very first assignments? – Joran Beasley Oct 01 '15 at 19:00
It's easier than you think to convert such a simple problem from a loop to a recursive function.
Start with a loop implementation:
n = 42
result = []
for i in range(n+1):
if n % i == 0:
result.append(i)
then write a function
def num_of_divisors_helper(i, n, result):
if <condition when a number should be added to result>:
result.append(n)
# Termination condition
if <when should it stop>:
return
# Recursion
num_of_divisors_helper(i+1, n, result)
Then you define a wrapper function num_of_divisors
that calls num_of_divisors_helper
. You should be able to fill the gaps in the recursive function and write the wrapper function yourself.
It's a simple, inefficient solution, but it matches your terms.

- 2,247
- 19
- 23
-
Not everything is about efficiency. "Nature is a tinkerer not an inventor" Recursion in its pure form is not only the foundations of computer science, it is part of every single evolutionary step. Mathematics is just the language we can communicate with nature, and I'm proposing to implement this postulate into a piece of code: Function(N)= 1^0 + 2^0 + 3^0 + 4^0 + 6^0 + 12^0 => How can I add the expoents? Instead of leaving them out of the recursive step as an integer, they have to be able to add squareroots, so = 1 + 1 + 1 + 1 + 1 + 1 = 6 – HandyFrank Oct 01 '15 at 09:11
-
@HandyFrank I mainly wrote that it's inefficient to hint that optimizations like stopping at (n+1)/2 are possible without saying too much. – cg909 Oct 01 '15 at 17:22
Without using %
def is_divisible(n, i, k):
if k > n:
return False
if n - i*k == 0:
return True
else:
return is_divisible(n, i, k+1)
def num_of_divisors(n, i=1):
if i > n/2:
return 1
if is_divisible(n, i, 1):
return 1 + num_of_divisors(n, i+1)
else:
return num_of_divisors(n, i+1)
num_of_divisors(42) -> 8
-
I have tried that one also! I was rejected rejected! No i=1. Only one input (N) - or (n). Defining two functions characterizes module: rejected - I've tried that one too! No doubts! Great code and I can do that one, just like it! However, this is part of my studies on theory of computer science, related to analytic number theory. Not seeking an efficient code. This instruction is to simply implement aliquot sum, exactly how the postulate states:num_of_divisor(12) = 1^0 + 2^0 + 3^0 + 4^0 + 6^0 + 12^0, which translates into: = 1 + 1 + 1 + 1 + 1 + 1 = 6. – HandyFrank Oct 01 '15 at 08:51