Understanding basic recursion using Python - python

I'm having trouble visualizing what actually happens in a recursive function. I've tried drawing activation frames and following the flow of data, but I get lost along the way. The visualizer at PythonTutor.com doesn't help as much as I'd hoped.
Here's a function that determines the number of digits in a number using recursion.
def digits(x):
if x > 0:
return 1 + digits(x // 10)
else:
return 0
Why is the 1 the only things that "survives" from one activation frame to another?

So if I am to consider x = 20, the flow would be as follows:
End: result = 2 <-----------.
| +
Start: digits(20) ==> returns 1 <-----------.
+ | +
digits(2) ==> returns 1 <-----------.
+ |
digits(0) ==> returns 0

With recursion, it's often useful to start with the base case. You can work it out on paper easily enough.
digits(0)
x = 0
if x > 0 # false
return 0
digits(0) == 0
digits(1)
x = 1
if x > 0 # true
return 1 + digits(1 // 10)
return 1 + digits(0) # 1//10==0
return 1 + 0 # digits(0)==0
return 1
digits(1) == 1
...
digits(10)
x = 10
x > 0 # true
return 1 + digits(10 // 10)
return 1 + digits(1)
return 1 + 1
return 2
digits(10) == 2
And so on.

Take digits(10) as an example:
digits(10):
if 10 > 0:
return 1 + digits(10 // 10)
<==>return 1 + digits(1)
<==>return 1 +
if 1 > 0:
return 1 + digits(1 // 10)
<==>return 1 + digits(0)
<==>return 1 +
if 0 > 0:
return 1 + digits(0 // 10)
else:
return 0
else:
return 0
else:
return 0
digits(0) returns 0;
digits(1 // 10) returns 1 + digits(0) = 1 + 0,
digits(10) returns 1 + digits(1 // 10) = 1 + 1 + 0 = 2

Related

find or generate all octal numbers from 0 to 8^10 that digit sum is equal to x

So given an input of 0o11110000000 base 8 ('0o' is ignored) i have to generate and count how many possible numbers that when the individual numbers are added they are the same. for example
0o1111000000 : 1 + 1 + 1 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 = 4
0o0000001111 : 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 = 4
0o0000000201 : 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 2 + 0 + 1 = 3
so for an input of 0o0000000001 i should get an answer of 10
0000000001
0000000010
0000000100
0000001000
0000010000
0000100000
0001000000
0010000000
0100000000
1000000000
My method is a very very brute force method in which i have to check every possible number from 0 to 7777 7777 77 base8. It uses the decimal represtation of the octal numbers and i use a recursive function to retrieve the octal sum of a number
How can i improve this to be a lot more faster. If possible no python modules as i doubt the machine running the program is unable to import a lot of stuff
def sum_of_octal_digits( n ):
if n == 0 :
return 0
else:
return int(n) % 8 + sum_of_octal_digits( int(n / 8) )
octInput = input("Enter hex: ")
int_octInput = int(octInput , 16)
total = sum_of_octal_digits(int_octInput )
allcombinations = list()
for i in range(pow(8,len(e[2:]))):
if sum_of_octal_digits(i) == total :
allcombinations.append(i)
print(len(allcombinations))
You're counting the number of sequences of {0, 1, 2, 3, 4, 5, 6, 7} of length n that sum to t. Call that value S[n, t].
There's a recurrence relation that S[n, t] satisfies:
S[0, 0] = 1
S[0, t] = 0 (t != 0)
S[n+1, t] = sum(S[n, t-d] for d=0...min(t, 7))
Once you have the recurrence relation, solving the problem using dynamic programming is straightforward (either by using memoization, or using a bottom-up table approach).
The program should run in O(nt) time and use O(nt) space.

understanding recursion stack sum_integers

I am doing a practice problem on recursion.
Implement sum_integers(n) to calculate the sum of all integers from 1 to đť‘› using recursion. For example, sum_integers(3) should return 6 ( 1+2+3 ).
I solved the problem without really understanding what I actually did...
def sum_integers(n):
if n == 0:
return 0
else:
return n + sum_integers(n-1)
pass
The base case, I understand.
lets say we call sum_integers(3)
sum_integers(3)
sum_integers(2)
sum_integers(1)
sum_integers(0)
return 0
I don't understand once I return 0 what/how is it going back up the stack.
In my head this is what's happening
0 + sum_integers(1) = 0 + 1
0 + 1 + sum_integers(2) = 0 + 1 + 2
0 + 1 + 2 + sum_integers(3) = 0 + 1 + 2 + 3
I don't know for sure though. I'm just trying to understand it a bit better.
The 0 + 1 + 2 + sum_integers(3) = 0 + 1 + 2 + 3 is not really correct, an easier way to see it could be
sum_integers(3) # go down in recursion
3 + sum_integers(2) # go down in recursion
3 + 2 + sum_integers(1) # go down in recursion
3 + 2 + 1 + sum_integers(0) # go down in recursion
3 + 2 + 1 + 0 # stop because 'return 0'
3 + 2 + 1 # go back and apply the plus
3 + 3 # go back and apply the plus
6 # go back and apply the plus

how does result = k + tri_recursion(k-1) give me an output of triangular numbers?

I'm currently learning about functions and I came across a recursions example on w3schools.com. This code is giving me a list of triangular numbers for an argument k > 0. My question is how exactly is it printing out a list of triangular numbers with "result" defined as result = k + tri_recursion(k-1) in the body of the code. The output for an input of k = 6, for example, gives me 1, 3, 6, 10, 15, 21 but I just don't understand how I'm getting a list of triangular numbers from such a simple setting of the return variable. Help would be much appreciated :)
def tri_recursion(k):
if k > 0:
result = k + tri_recursion(k-1)
print(result)
else:
result = 0
return result
print("\n\nexample result")
tri_recursion(6)
you need create a list to storage numbers:
tri_list = []
def tri_recursion(k):
if k > 0:
result = k + tri_recursion(k-1)
tri_list.append(result)
print(result)
else:
result = 0
return result
print("\n\nexample result")
tri_recursion(6)
print(tri_list)
Then you have:
k = 6
6 + tri_recursion(5)
5 + tri_recursion(4)
4 + tri_recursion(3)
3 + tri_recursion(2)
2 + tri_recursion(1)
1 + tri_recursion(0)
1 + 0 = 1
2 + 1 = 3
3 + 3 = 6
4 + 6 = 10
5 + 10 = 15
6 + 15 = 21
This happens because you are printing the sum of the previous numbers in each return of each recursion

Is there a way for a for loop to not go back to the code on top if the next if statement is true?

a = 0
b = 0
for x in range (100):
a = a + 1
if a == 10:
b = b + 1
print(a)
print(b)
The outcome
99
1
What I want
10
90
IIUC, this should do the trick:
a = 0
b = 0
for x in range (100):
if a < 10:
a = a + 1
else:
b = b + 1
But to simplify further, you can use python's assignment operator, a += 1 syntax, which increments the value of a by 1:
a = 0
b = 0
for x in range (100):
if a < 10:
a += 1
else:
b += 1
Add a conditional check.
a = 0
b = 0
for x in range (100):
if (a % 10 != 0 or a==0):
a = a + 1
else:
b = b + 1
print(a)
print(b)
Just for fun:
a, b = 0, 0
for x in range(100):
add = a % 10 != 0 or a == 0
a += add
b += not add
This uses the fact that a bool is an int although I don’t advise it as it’s not too readable

Doubling every second digit in python

I would like to double the value of every second digit and then add up the digits that are in their tens. Finally adding all the digits together
E.g: 123456789 -> 1 4 3 8 5 12 7 16 9 -> 1 4 3 8 5 3 7 7 9 -> 47
edit: the user would input any number and the function would still work eg: 5153 -> 5 2 5 6 -> 18
-SORRY first post I'm still getting used to this-
So I would like my function to
1. Reverse the inputted number
2. Double the value of the second digit
3. Sum all the digits together
4. Check if it's divisible by 7
Here is my code so far
my testing
def checksum(num):
#print(rev)
odd_digit = ""
even_digit = ""
even_sum = 0
odd_sum = 0
total_sum = 0
if num < 10 and num != 7:
return False
else:
return True
rev = (num[::-1])
for i in range(len(rev)):
if i % 2 == 0:
odd_digit += rev[i]
else:
even_digit += rev[i]
#print(even_digit)
even_digit = int(even_digit)
while even_digit > 0:
even_digit, even_sum = even_digit//10,even_sum+(even_digit%10)
#print(even_sum)
even_sum_2 = even_sum * 2
#print(even_sum_2)
odd_digit = int(odd_digit)
while odd_digit > 0:
odd_digit, odd_sum = odd_digit//10,odd_sum+(odd_digit%10)
#print(odd_sum)
total_sum = even_sum_2 + odd_sum
#print(total_sum)
if total_sum % 7 == 0:
return True
else:
return False
print(checksum(12345678901))
Try using this sum with a map, and a list comprehension:
>>> sum(map(int,''.join([str(int(v)*2) if i%2 else v for i,v in enumerate(s)])))
47
Or use:
>>> sum([sum(map(int,str(int(v)*2))) if i%2 else int(v) for i,v in enumerate(s)])
47
sum([sum(map(int, str(i * 2))) if i % 2 == 0 else i for i in range(1, 10)])

Categories

Resources