create recursive power of 2 '*' in python - python

In pyschools, I am stuck in the power of 2 recursive function
>>> createStars(0) # 2 to power of 0 = 1
'*'
>>> createStars(1) # 2 to power of 1 = 2
'**'
>>> createStars(2) # 2 to power of 2 = 4
'****'
>>> createStars(3) # 2 to power of 3 = 8
'********'
What I am trying to do is as following:
def createStars(x):
if x == 0:
return '*'
else:
return '*' * x + createStars(x-1)
However, this seems to be a summation of 'x' not power of 2.
Meaning, this will break when the x is higher than 2
I know how to do the power of 2 recursively but no idea where to change to make createStars() work.
def power(x, n):
if n == 0:
return 1
else:
return x * power(x, n-1)
PS. I know it is easy to use non-recursive method to solve it.
But would like to seek advice how to do it in recursive way.
Thanks.

def createStars(x):
if x == 0:
return '*'
else:
return createStars(x-1) * 2
(Each step back in the recursion doubles the number of stars in the output string).

You're very close!
I would suggest comparing the two pieces of code you gave us. (I'm going to rename it a bit to make the analogy more clear):
def createStars(n):
if n == 0:
return '*'
else:
return '*' * n + createStars(n-1)
def power(x, n):
if n == 0:
return 1
else:
return x * power(x, n-1)
They have almost exactly the same structure. In particular, the last line of each has a slightly different structure.
In the (working) power, you multiply the result for n-1 by x. So, when computing the power(2, 6), you increase power(2, 5) by 2. (i.e. you multiply 32 by 2 to get 64).
In the (not working) createStars, you're not multiplying the result for the n-1 case by anything; you're just adding stuff to the start of it. What if you change it to make the structures match?
Also, you should check what the result is for createStars(1).

Related

Is ther any other way to get sum 1 to 100 with recursion?

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))

How return works in recursion?

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

A twist in Fibonacci's sequence in Python

I am studyng recursion in Python and now I am having a problem with this exercise:
Remember that Fibonacci's sequence is a sequence of numbers where every number is the sum of the previous two numbers.
For this problem, implement Fibonacci recursively, with a twist! Imagine that we want to create a new number sequence called Fibonacci-3. In Fibonacci-3, each number in the sequence is the sum of the previous three numbers. The
sequence will start with three 1s, so the fourth Fibonacci-3
number would be 3 (1+1+1), the fifth would be 5 (1+1+3), the sixth would be 9 (1+3+5), the seventh would be 17 (3+5+9), etc.
Name your function fib3, and make sure to use recursion.
The lines below will test your code.
If your function is correct, they will print 1, 3, 17, and 57.
print(fib3(3))
print(fib3(4))
print(fib3(7))
print(fib3(9))
This is the code until now:
def fib3(n):
if n <= 1:
return n
else:
return(fib3(n-1) + fib3(n-2) + fib3(n-3))
But the results are: 1, 2, 11, 37
Can you help me please to correct it?
The same thing other people are saying
As others have noted, you have to return 1 when n <= 3
def fib3 (n):
if n <= 3:
return 1
else:
return fib3(n - 1) + fib3(n - 2) + fib3(n - 3)
print(fib3(3)) # 1
print(fib3(4)) # 3
print(fib3(7)) # 17
print(fib3(9)) # 57
... but you can do better than that
But that definition of fib3 is junk. It does an insane amount of computation duplication. For example, fib3(40) takes over 30 minutes to compute due to O(n3) complexity
Consider an approach that uses an auxiliary loop with state variables – The O(n) complexity allows it to compute the same result in less than a millisecond.
def fib3 (n):
def aux (n,a,b,c):
if n == 1:
return a
else:
return aux(n-1,b,c,a+b+c)
return aux(n,1,1,1)
print(fib3(3)) # 1
print(fib3(4)) # 3
print(fib3(7)) # 17
print(fib3(9)) # 57
print(fib3(40)) # 9129195487
Fibonacci as a generic program: fibx
We can make generic the entire process of generating fibonacci sequences, but first we have to address something with your fib3 function. In general, Fibonacci numbers have a 0th term - ie, fib(0) == 0, fib(1) == 1. In your function, it looks like the first number is fib3(1), where fib3(0) would produce an undefined result.
Below, I'm going to introduce fibx which can take any binary operator and any seed values and create any fibonacci sequence we can imagine
from functools import reduce
def fibx (op, seed, n):
[x,*xs] = seed
if n == 0:
return x
else:
return fibx(op, xs + [reduce(op, xs, x)], n - 1)
Now we can implement standard fibonacci using fibx with the add (+) operator and seed values 0,1
from operator import add
def fib (n):
return fibx(add, [0,1], n)
print(fib(0)) # 0
print(fib(1)) # 1
print(fib(2)) # 1
print(fib(3)) # 2
print(fib(4)) # 3
print(fib(5)) # 5
Implementing fib3 using fibx
We can use the same fibx with the add operator to implement your fib3 function, but because of your 1-based index, notice I'm offsetting n by 1 to get the correct output
from operator import add
def fib3 (n):
return fibx(add, [1,1,1], n-1)
print(fib3(3)) # 1
print(fib3(4)) # 3
print(fib3(7)) # 17
print(fib3(9)) # 57
I'd recommend you start with a 0-based index tho. This means 0-based index fib3(2) is actually equal to your 1-based index of fib3(3)
from operator import add
def fib3 (n):
return fibx(add, [1,1,1], n)
print(fib3(2)) # 1
print(fib3(3)) # 3
print(fib3(6)) # 17
print(fib3(8)) # 57
Any imaginable sequence using fibx
And of course you can make any other sequence you can imagine. Here we make weirdfib that uses multiplication (*) instead of addition (+) to combine terms and has a starting seed of [1,2,3]
from operator import mul
def weirdfib (n):
return fibx(mul, [1,2,3], n)
print(weirdfib(0)) # 1
print(weirdfib(1)) # 2
print(weirdfib(2)) # 3
print(weirdfib(3)) # 6
print(weirdfib(4)) # 36
print(weirdfib(5)) # 648
print(weirdfib(6)) # 139968
Your problem description tells you why:
The sequence will start with three 1s
Your solution, however only returns 1 for n == 1 or lower:
if n <= 1:
return n
This means that for n == 2 (which should still return 1), you'd instead return fib3(2-1) + fib3(2-2) + fib3(2-3), or fib3(1) + fib3(0) + fib(-1), which thanks to the above test, then bottoms out to produce 1 + 0 + -1 == 0.
For n == 3, you'd return fib3(2) + fib3(1) + fib3(0); we worked out above that fib3(2) is 0, so the end result is 0 + 1 + 0 is the 1 you observed.
Finally, the 4th fib3 number (n == 4), does not return 3, but fib3(3) + fib3(2) + fib3(1) == 1 + 0 + 1 == 2.
Change that first test return 1 for n <= 3, to fix those first 3 values in the series:
def fib3(n):
if n <= 3:
return 1
else:
return fib3(n-1) + fib3(n-2) + fib3(n-3)
Now the code passes the given tests:
>>> def fib3(n):
... if n <= 3:
... return 1
... else:
... return fib3(n-1) + fib3(n-2) + fib3(n-3)
...
>>> print(fib3(3))
1
>>> print(fib3(4))
3
>>> print(fib3(7))
17
>>> print(fib3(9))
57
If n <= 1, the situation is a little more complex than just return n.
Consider the case of n = 4: your recursive call will be fib(3), fib(2), and fib(1).
The lattermost returns 1 immediately, which is what you want. However, the two recursive calls do some weird things. fib(2) recurses into fib(1), fib(0), and fib(-1), the return values for which basically hand back a big fat 0. fib(3) recurses into fib(2) (which we saw is 0), fib(1) (which works, and is 1), and fib(0) (which is also 0).
Hence, you get the 1 from the very beginning, and the 1 from the recursed fib(1) component of fib(3). There's your 2!
Basically, you want to make sure your base case can't return a negative number. Fix that (return either 1 or 0), and you should be good. As Martijn Pieters mentioned, you can also make your base case n <= 3 and it should achieve the same effect.
Let me contribute with perhaps the most optimal "pythonic" answer.
The main point is to avoid recursive function calls to optimise the efficiency of the code. Pythonic way of thinking would involve the following compact code, which is an iterative creation of the Fibonacci sequence of n numbers, including the seed numbers [1, 1, 1].
def fibonacci_sequence(n):
x = [1, 1, 1]
[x.append(x[-1] + x[-2] + x[-3]) for i in range(n - len(x))]
return x
import time
n = int(raw_input("Enter the size of Fibonacci-3 sequence: "))
start_time = time.time()
print fibonacci_sequence(n)
print "The time to compute the Fibonacci-3 sequence is: %s" % (time.time() - start_time)

Python: Streamlining Code for Brown Numbers

I was curious if any of you could come up with a more streamline version of code to calculate Brown numbers. as of the moment, this code can do ~650! before it moves to a crawl. Brown Numbers are calculated thought the equation n! + 1 = m**(2) Where M is an integer
brownNum = 8
import math
def squareNum(n):
x = n // 2
seen = set([x])
while x * x != n:
x = (x + (n // x)) // 2
if x in seen: return False
seen.add(x)
return True
while True:
for i in range(math.factorial(brownNum)+1,math.factorial(brownNum)+2):
if squareNum(i) is True:
print("pass")
print(brownNum)
print(math.factorial(brownNum)+1)
break
else:
print(brownNum)
print(math.factorial(brownNum)+1)
brownNum = brownNum + 1
continue
break
print(input(" "))
Sorry, I don't understand the logic behind your code.
I don't understand why you calculate math.factorial(brownNum) 4 times with the same value of brownNum each time through the while True loop. And in the for loop:
for i in range(math.factorial(brownNum)+1,math.factorial(brownNum)+2):
i will only take on the value of math.factorial(brownNum)+1
Anyway, here's my Python 3 code for a brute force search of Brown numbers. It quickly finds the only 3 known pairs, and then proceeds to test all the other numbers under 1000 in around 1.8 seconds on this 2GHz 32 bit machine. After that point you can see it slowing down (it hits 2000 around the 20 second mark) but it will chug along happily until the factorials get too large for your machine to hold.
I print progress information to stderr so that it can be separated from the Brown_number pair output. Also, stderr doesn't require flushing when you don't print a newline, unlike stdout (at least, it doesn't on Linux).
import sys
# Calculate the integer square root of `m` using Newton's method.
# Returns r: r**2 <= m < (r+1)**2
def int_sqrt(m):
if m <= 0:
return 0
n = m << 2
r = n >> (n.bit_length() // 2)
while True:
d = (n // r - r) >> 1
r += d
if -1 <= d <= 1:
break
return r >> 1
# Search for Browns numbers
fac = i = 1
while True:
if i % 100 == 0:
print('\r', i, file=sys.stderr, end='')
fac *= i
n = fac + 1
r = int_sqrt(n)
if r*r == n:
print('\nFound', i, r)
i += 1
You might want to:
pre calculate your square numbers, instead of testing for them on the fly
pre calculate your factorial for each loop iteration num_fac = math.factorial(brownNum) instead of multiple calls
implement your own, memoized, factorial
that should let you run to the hard limits of your machine
one optimization i would make would be to implement a 'wrapper' function around math.factorial that caches previous values of factorial so that as your brownNum increases, factorial doesn't have as much work to do. this is known as 'memoization' in computer science.
edit: found another SO answer with similar intention: Python: Is math.factorial memoized?
You should also initialize the square root more closely to the root.
e = int(math.log(n,4))
x = n//2**e
Because of 4**e <= n <= 4**(e+1) the square root will be between x/2 and x which should yield quadratic convergence of the Heron formula from the first iteration on.

Incorrect answer while calculating pi value from given series

I was trying to calculate value of pi using this formula:
I had written this code for finding it for a given n:
def pisum(n):
sum=3.0
x=2.0
while (n>0):
if n%2==1:
sum=sum+(4/(x*(x+1)*(x+2)))
else :
sum=sum-(4/(x*(x+1)*(x+2)))
x=x+2
n=n-1
return str(sum)
It runs fine for n=0 and n=1 and gives output 3.0, 3.16666666667. But for n=50 the output should be 3.1415907698497954 but it is giving 2.85840923015. Why so much difference? Please help to correct if i had done something wrong.
The problem is that you are using n%2 in order to determine whether to subtract or add. It is not the amount of loops that you start with that should matter, but which loop you're in. To see that, try using your function for an odd number, e.g. 51 and you will see that it will give you a correct answer.
To explain further, if you start with n=50, you will initially subtract (4/(x*(x+1)*(x+2))) from 3 rather than add to it, but if you start with n=51, you will initially add.
If you modify your function as follows:
def pisum(n):
sum = 3.0
x = 2.0
for i in range(n):
if i % 2 == 0:
sum = sum + (4 / (x * (x + 1) * (x + 2)))
else:
sum = sum - (4 / (x * (x + 1) * (x + 2)))
x = x + 2
return str(sum)
you will always get a correct result.
You made a small mistake.
One correct program:
def pisum(n):
sum = 3.
for i in xrange(2, 2*n+2, 2):
sum += (4. if (i&2) == 2 else -4.)/i/(i+1)/(i+2)
return sum
Being more conservative with number of lines:
def pisum(n):
return 3. + sum([(4. if (i&2) == 2 else -4.)/i/(i+1)/(i+2) for i in xrange(2,2*n+2,2)])
Mistake in yours:
You are iterating on n in reverse, thus one time (odd value of n) you are calculating:
and for another value of n (even value apart from 0) you are calculating

Categories