I'm working on a homework assignment that asks me to create a Pascal Triangle using a recursive function. Below is what I've managed so far along with what I was given to work with. I'm quite new to Python and programming so I've got no idea where to head from here, any help would be appreciated!
def combination(n, k):
print((n - 1) / (k - 1)) + ((n - 1) / k)
def pascals_triangle(rows):
for row in range(rows):
answer = ""
for column in range(row + 1):
answer = answer + combination(row, column) + "\t"
print(answer)
pascals_triangle(5)
You are not, in fact, using recursion at all in your answer. I think you are trying to code the formula nCk = (n-1)C(k-1) + (n-1)Ck. You need, therefore, to call combination from within itself (with a guard for the "end" conditions: nC0 = nCn = 1):
def combination(n, k):
if k == 0 or k == n:
return 1
return combination(n - 1, k - 1) + combination(n - 1, k)
def pascals_triangle(rows):
for row in range( rows):
answer = ""
for column in range( row + 1):
answer = answer + str(combination(row, column)) + "\t"
print(answer)
pascals_triangle(5)
Output:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
Note that this is a spectacularly inefficient way of doing this: you are calling combination many, many times with the same arguments each time you get a binomial coefficient. You might consider caching the coefficients you find as you go along.
The other problem with your code is that your combination function wasn't actually returning anything, it was simply printing a value and exiting (returning None).
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 10 months ago.
Improve this question
The use of for loops is not allowed. This program is designed to calculate values up to number 'n' which is a value entered by the user. Help on this would be appreciated. A photo of the problem and my code so far is listed below:
import math
counterN = 0 #Numerator
counterD = 0 #Denominator
divNumber = 0 #Numerator/Denominator
nValue = 0 #Variable to add numberator values to
dValue = 0 #Variable to add denominaor values to
#Prompts user for a
print("Please enter a value for calculation: ")
number = int(input())
if (number <= 0):
print("Invalid input given.")
#Adds the numerator up to number entered by user
while (counterN <= number):
counterN = counterN + 1
nValue += counterN
#Denominator calculation
counterD = counterD + 1
dValue += counterD
divNumber = nValue / dValue
divNumber += divNumber
#Outputs value to user
print("The result is" , divNumber)
print(counterN, nValue)
You can use recursion for such problems. I've written a recursive solution for you which I found very intuitive-
global SUM
SUM = 0
def fracSUMCalc(n):
if n == 1:
return 1
SUM = fracSUMCalc(n-1) + (sum(range(1, n+1)) / n)
return SUM
print(fracSUMCalc(n=998))
This prints out 249749.5 which is the answer to the sum of your series till n=998. You can vary n as per your need.
Please note that this solution will work fine on any standard modern day laptop till n=998. For n>998, you'd either have to increase your machine's recursion depth limit or use a different approach to develop a more efficient program.
There is a solution that just uses no loops or recursion at all, just maths
def frac_series_sum(n):
return n + sum(range(n)) * 0.5
print(frac_series_sum(1)) # 1.0
print(frac_series_sum(5)) # 10.0
print(frac_series_sum(100)) # 2575.0
It can be shown (see below) that your sum is equal to
for any natural number n.
Thus, this function calculates the sum you want. It does not involve any recursion, for loops or any kind of iteration (it is O(1)):
def my_calc(n):
"Returns 1/1 + (1 + 2)/2 + ... + (1 + 2 + ... + n)/n"
return 0.25 * n * (n + 3)
This is as efficient as it gets.
If you are not allowed to use the solution above and you need to use a while loop:
def my_inefficient_calc(n):
"Returns 1/1 + (1 + 2)/2 + ... + (1 + 2 + ... + n)/n"
result = 0
i = 1
while (i <= n):
result += (sum(range(1, i + 1))) / i
i += 1
return result
If you are not allowed to use the built-in sum function, you can calculate the sum using a nested while loop:
def even_less_efficient(n):
"Returns 1/1 + (1 + 2)/2 + ... + (1 + 2 + ... + n)/n"
result = 0
i = 1
while (i <= n):
inner_sum = 0
k = 1
while (k <= i):
inner_sum += k
k += 1
result += inner_sum / i
i += 1
return result
i is a loop variable (counter) for the outer loop. It ranges from i = 1 up to n.
k is a loop variable (counter) for the inner loop. It ranges from k = 1 up to i.
The inner loop is responsible for calculating the sum in the numerator for each term. This sum is stored in inner_sum.
Once the sum is calculated for a given i (i.e. once we are done with the inner loop), we divide this sum by i to get one of the terms in the mathematical expression.
The outer loop is responsible for summing all of the terms from i = 1 up to n.
Intuitive Proof
How did I arrive at this?
You want a program that calculates the following sum:
This is an elegant solution that has stuck with me for a long time that I will never forget. I once learned in real analysis of a famous mathematician who at the age of 5 (if I remember correctly) reasoned that the sum of i from i = 1 up to k is:
He did so by writing out the sum twice, but the second in reverse order:
(sum of i from i = 1 to k) = 1 + 2 + ... + (k - 1) + k
(sum of i from i = 1 to k) = k + (k - 1) + ... + 2 + 1
----------------------------------------------------------
(k+1)+ (k+1) +... + (k+1) + (k+1) # k terms
He noticed that each sum has k numbers and the sum of each column is equal to k + 1. So, if you add the two sums, you get
2 * (sum of i from i = 1 to k) = k * (k + 1)
Thus
(sum of i from i = 1 to k) = (k * (k + 1)) / 2
which is the same as the result in the second image above.
Substitution of this result into the left-hand-side of the expression in the first image:
Now apply the result that we derived again to the last expression above:
Thus
or
0.25 * n * (n + 3)
Note: A formal proof of the above result would be a proof by induction to show it is true for any natural number n. This proof by induction part is the easy part. I have omitted such a proof as the above should be obvious to anyone that sees it.
Bro, I just did easier
counterN = 1 #Numerator
result = []
#Prompts user for a
print("Please enter a value for calculation: ")
number = int(input())
if (number <= 0):
print("Invalid input given.")
#Adds the numerator up to number entered by user
while (counterN <= number):
numerator = sum(range(counterN+1))
denominator = counterN
result.append(numerator / denominator)
#solucion
counterN += 1
#Outputs value to user
print("The result is" , sum(result))
I'm studing recursive function and i faced question of
"Print sum of 1 to n with no 'for' or 'while' "
ex ) n = 10
answer =
55
n = 100
answer = 5050
so i coded
import sys
sys.setrecursionlimit(1000000)
sum = 0
def count(n):
global sum
sum += n
if n!=0:
count(n-1)
count(n = int(input()))
print(sum)
I know it's not good way to get right answer, but there was a solution
n=int(input())
def f(x) :
if x==1 :
return 1
else :
return ((x+1)//2)*((x+1)//2)+f(x//2)*2
print(f(n))
and it works super well , but i really don't know how can human think that logic and i have no idea how it works.
Can you guys explain how does it works?
Even if i'm looking that formula but i don't know why he(or she) used like that
And i wonder there is another solution too (I think it's reall important to me)
I'm really noob of python and code so i need you guys help, thank you for watching this
Here is a recursive solution.
def rsum(n):
if n == 1: # BASE CASE
return 1
else: # RECURSIVE CASE
return n + rsum(n-1)
You can also use range and sum to do so.
n = 100
sum_1_to_n = sum(range(n+1))
you can try this:
def f(n):
if n == 1:
return 1
return n + f(n - 1)
print(f(10))
this function basically goes from n to 1 and each time it adds the current n, in the end, it returns the sum of n + n - 1 + ... + 1
In order to get at a recursive solution, you have to (re)define your problems in terms of finding the answer based on the result of a smaller version of the same problem.
In this case you can think of the result sumUpTo(n) as adding n to the result of sumUpTo(n-1). In other words: sumUpTo(n) = n + sumUpTo(n-1).
This only leaves the problem of finding a value of n for which you know the answer without relying on your sumUpTo function. For example sumUpTo(0) = 0. That is called your base condition.
Translating this to Python code, you get:
def sumUpTo(n): return 0 if n==0 else n + sumUpTo(n-1)
Recursive solutions are often very elegant but require a different way of approaching problems. All recursive solutions can be converted to non-recursive (aka iterative) and are generally slower than their iterative counterpart.
The second solution is based on the formula ∑1..n = n*(n+1)/2. To understand this formula, take a number (let's say 7) and pair up the sequence up to that number in increasing order with the same sequence in decreasing order, then add up each pair:
1 2 3 4 5 6 7 = 28
7 6 5 4 3 2 1 = 28
-- -- -- -- -- -- -- --
8 8 8 8 8 8 8 = 56
Every pair will add up to n+1 (8 in this case) and you have n (7) of those pairs. If you add them all up you get n*(n+1) = 56 which correspond to adding the sequence twice. So the sum of the sequence is half of that total n*(n+1)/2 = 28.
The recursion in the second solution reduces the number of iterations but is a bit artificial as it serves only to compensate for the error introduced by propagating the integer division by 2 to each term instead of doing it on the result of n*(n+1). Obviously n//2 * (n+1)//2 isn't the same as n*(n+1)//2 since one of the terms will lose its remainder before the multiplication takes place. But given that the formula to obtain the result mathematically is part of the solution doing more than 1 iteration is pointless.
There are 2 ways to find the answer
1. Recursion
def sum(n):
if n == 1:
return 1
if n <= 0:
return 0
else:
return n + sum(n-1)
print(sum(100))
This is a simple recursion code snippet when you try to apply the recurrent function
F_n = n + F_(n-1) to find the answer
2. Formula
Let S = 1 + 2 + 3 + ... + n
Then let's do something like this
S = 1 + 2 + 3 + ... + n
S = n + (n - 1) + (n - 2) + ... + 1
Let's combine them and we get
2S = (n + 1) + (n + 1) + ... + (n + 1) - n times
From that you get
S = ((n + 1) * n) / 2
So for n = 100, you get
S = 101 * 100 / 2 = 5050
So in python, you will get something like
sum = lambda n: ( (n + 1) * n) / 2
print(sum(100))
def sum_it(n,y):
if n ==0:
return y
else:
return sum_it(n-1,n+y)
required output for sum_it(3,4)i.e. (3+2+1)+4 must be 10
but obtained output is 5
Please how the return really works ?
Altough unclear, it seems like what you need when calling sum_it(n,y) is the sum of natural numbers from 1 to n plus y.
This initial sum is also known as "nth" triangular number.
If that's the case, you actually don't need recursion:
def sum_it(n,y):
return (n*(n+1))//2 + y
If recursion is a must:
def sum_it(n,y):
if (n > 1):
return n + sum_it(n-1,y)
return n + y
Feel free to ask if any doubt remains.
If you intended to sum like (3+2+1) + 4, this code will works.
def sum_it(n,y):
if( n == 1):
return y + 1
else:
return(n + sum_it(n-1,y))
For example, sum_it(3,4) works like below
sum_it(3,4) returns 3 + sum_it(2,4)
sum_it(2,4) returns 2 + sum_it(1,4)
sum_it(1,4) returns 1 + 4
It means
sum_it(3,4) returns 3 + 2 + 1 + 4
I want to use recursion on continuous fractions, which will go like this.
The user will input a value of n, and if n is 3, then it will go like this:
2 + 1/ (1 + 1 / (2 + 2/ (3 + 3 / 4)))
where the first 2 + 1/ are fixed in the equation, now we have to calculate the numbers behind it. That is the part where i have been scratching my head for days. Someone taught me that it is possible to use recursion to calculate that part, but I have been trying to learn how to use it but mine just loops forever or has a recursionError
n = int(input("Enter n value: "))
result = 0
fract = 0
def frac(j):
global fract
for i in range(j):
fract = (j + j)/ frac(j)
return fract
def calc_e():
e = 2 + 1/ frac(n) / n + 1
return e
print(calc_e())
#formula = 2 + 1 / (1 + 1 / (2 + 2 / (3 + 3 / (4 + 4 / (...)))))
TLDR: I dont know how to calculate the part after 2 + 1/
There is no need to use a global variable; I don't see where the need for a for-loop arises either. And as previous answers have pointed out, you have a few algebra mistakes.
You should add a stopping condition argument to frac to stop it from infinitely recursing. Return the value j if this is hit:
# max number of terms n
def frac(j, n):
if j >= n: return n
return j + j / frac(j+1, n)
# remember to pass 1.0 instead of 1, or cast to float in frac
# to avoid integer division which will truncate all fractions
def calc_e(n=100):
return 2 + 1 / frac(1.0, n)
This returns:
n calc_e(n)
----------------------
2 2.666666666666667
4 2.716981132075472
8 2.718281657666404
16 2.718281828459045
32 2.718281828459046
64 2.718281828459046
128 2.718281828459046
256 2.718281828459046
512 2.718281828459046
A higher number of recursions was not possible due to stack overflow.
You can use simple recursion:
#2 + 1/ (1 + 1 / (2 + 2/ (3 + 3 / 4)))
def get_equation(_to_val, string_rep = False):
if string_rep:
def calculate(start, end):
return '{}+{}/({})'.format(start, start, calculate(start+1, end) if start < end else end+1)
return '2+1/({})'.format(calculate(1, _to_val))
def calculate(start, end):
return start+start/(calculate(start+1, end) if start < end else end+1)
return calculate(1, _to_val)
print(get_equation(3))
print(get_equation(3, True))
Output:
1.3947368421052633
2+1/(1+1/(2+2/(3+3/(4))))
You have some basic problems in your frac routine
def frac(j):
global fract
for i in range(j):
fract = (j + j)/ frac(j)
return fract
You haven't settled on how to communicate the result: you keep updating the global fract, but returning its value afterward. Only one of these should be necessary.
Similarly, you are stepping through the continued fraction with both a for loop and recursion. You should use only one of these.
You have no base case on your recursion: there's nothing to tell the algorithm that it has "hit bottom". Every time you hit the computation step, you recur on frac; there's no logic path that does not recur. This is the main reason you get infinite recursion. If these are new concepts for you, please work through a tutorial on recursion; that will explain it at least as well as we can here.
Your algebra is wrong: (j + j)/ frac(j) is the wrong order of operations, and gives you merely 2*j / frac(j). You should have something like j + j/frac(j+1).
Is that enough hints to get you to a more useful coding practice? You may also need help debugging; a few well-chosen print statements will usually show you what's happening. See this lovely debug blog for help.
I studied Python Recursion Recently. There are few things that i am finding difficult to understand.
looks like Counting and Adding Elements of a list Through Recursion in python is almost done in a similar way. Can someone Please explain me why the calls are acting differently just by adding '1' and 'num[0]' for the below return calls:
return "*1*"+sum(num[1:]) and return "*num[0]*"+sum(num[1:])
Code for Counting Numbers in a list:
def count(num):
if len(num) == 0:
return 0
return 1+count(num[1:])
print(count([1,2,3,4,5,6,11]))
Output: 7
Code for Adding Elements in a List:
def sum(num):
if len(num) == 0:
return 0
return num[0]+sum(num[1:])
print(sum([1,2,3,4,5,6,11]))
Output: 32
Can someone please explain the return statement and in both of above recursion programs.
Any information that makes sense to me will be of a great help. Thanks a lot.
First, let’s write this with a loop, which is more pythonic and also probably easier for a novice to understand:
def count(nums):
res = 0
for num in nums:
res = 1 + res
return res
def sum(nums):
res = 0
for num in nums:
res = num + res
return res
The same one-word difference in the + operation. But now, hopefully you can understand why it’s different. The first one starts with 0, and adds 1 to that, once per element. The second one starts with 0, and adds the element to that, once per element.
The recursive code is doing basically the same thing, except a bit more complicated.
What it’s actually doing is pushing each element onto a stack, then starting with 0, then popping the stack until it’s empty, adding 1 or the element (respectively) for each element popped off the stack.1
But pushing a bunch of elements onto a stack and popping them off gives you the same elements, just in reverse. And adding 1 once per element, or adding up all of the elements, does the same thing counting backward as counting forward.
If you still don't understand, you should try stepping through the calls. Normally I'd suggest using an interactive visualizer, like Python Tutor, but since this problem seems specifically designed to make you think functionally, let's do it that way.
Imagine that function calls in Python were just a matter of substituting in the arguments for the parameters.2
So:
count([1,2,3])
= 0 if len([1,2,3]) == 0 else 1 + count([2,3])
= 1 + count([2,3])
= 1 + (0 if len([2,3]) == 0 else 1 + count([3]))
= 1 + (1 + count([3]))
= 1 + (1 + (0 if len([3]) == 0 else 1 + count([])))
= 1 + (1 + (1 + count([])))
= 1 + (1 + (1 + (0 if len([]) == 0 else 1 + count([])))))
= 1 + (1 + (1 + (0)))
= 1 + (1 + (1))
= 1 + (2)
= 3
sum([5,10,1])
= 0 if len([5,10,1]) == 0 else 5 + count([10,1])
= 5 + count([10,1])
= 5 + (0 if len([10,1]) == 0 else 10 + count([1]))
= 5 + (10 + count([3]))
= 5 + (10 + (0 if len([3]) == 0 else 1 + count([])))
= 5 + (10 + (1 + count([])))
= 5 + (10 + (1 + (0 if len([]) == 0 else ??? + count([])))))
= 5 + (10 + (1 + (0)))
= 5 + (10 + (1))
= 5 + (11)
= 16
Also, notice that ??? above. What is num[0] when num is empty? That would raise an exception—but, because we never use that branch, it doesn't matter what it would have done.
1. It’s also making a whole lot of useless list copies for no reason but to let the author pretend he’s programming in Scheme rather than Python, but let’s ignore that.
2. They aren't—but as long as you aren't doing assignments or any other kind of mutation, you can't actually tell the difference. Which is why people who love pure functional languages—where you can't do assignments, etc.—love them.