I'm trying to calculate the nth term but its giving me wrong answers
import math
def bernoulli(m):
if m == 0:
return 1
else:
t = 0
for k in range(0, m):
t += math.comb(m, k) * bernoulli(k) / (m - k + 1)
return 1 - t
def pn(n, x):
sum = 0
for i in range(n):
sum += ((bernoulli(2 * i)) / math.factorial(2 * i)) * (-4**i) * (1 - (4**i)) * (x**((2 * i) - 1))
Equation:
Here are a few comments:
In python, the convention is to include the start, and exclude the end. list(range(1,4)) is only [1, 2, 3], not [1,2,3,4]. Thus your Bernouilli loop should be for k in range(0, m+1) and your pn loop should be for i in range(1, n+1).
Exponentiation has a higher precedence than most operators. -4**i is parsed as -(4**i), not as (-4)**i.
sum is already the name of a builtin function in python. It is very strongly advised not to shadow the names of builtins. Call that variable s or total or something else, not sum.
Finally, the code becomes:
import math
def bernoulli(m):
if m == 0:
return 1
else:
t = 0
for k in range(0, m+1):
t += math.comb(m, k) * bernoulli(k) / (m - k + 1)
return 1 - t
def pn(n, x):
s = 0
for i in range(1, n+1):
s += ((bernoulli(2 * i)) / math.factorial(2 * i)) * ((-4)**i) * (1 - (4**i)) * (x**(2 * i - 1))
return s
And, using builtin function sum:
import math
def bernoulli(m):
if m == 0:
return 1
else:
return 1 - sum(math.comb(m, k) * bernoulli(k) / (m - k + 1)
for k in range(0, m+1))
def pn(n, x):
return sum((bernoulli(2 * i)) / math.factorial(2 * i)) * ((-4)**i) * (1 - (4**i)) * (x**(2 * i - 1)
for i in range(1, n+1))
I'm pretty new in python and I'm having trouble doing this double summation.
I already tried using
x = sum(sum((math.pow(j, 2) * (k+1)) for k in range(1, M-1)) for j in range(N))
and using 2 for loops but nothing seens to work
You were pretty close:
N = int(input("N: "))
M = int(input("M: "))
x = sum(sum(j ** 2 * (k + 1) for k in range(M)) for j in range(1, N + 1))
It also can be done with nested for loops:
x = 0
for j in range(1, N + 1): # [1, N]
for k in range(M): # [0, M - 1]
x += j ** 2 * (k + 1)
After a little math...
x = M * (M+1) * N * (N+1) * (2*N+1) // 12
I have the following code:
n = int(input())
a, b, c = map(int, input().split())
result = sum(s // c + 1 for i in range(n) for j in range(n - a * i) if (s := n - a * i - b * j - 1) >= 0)
print(result)
But I have an error that Python 3.7 does not support assignment expressions in this part (s := n - a * i - b * j - 1). How can I rewrite it? I want to rewrite it to python3.7
The simple, though repetitive, fix is to "inline" the value of s.
result = sum((n - a * i - b * j - 1) // c + 1
for i in range(n)
for j in range(n - a * i) if n - a * i - b * j - 1 >= 0)
Start with converting the generator expression to plain code and then it is a simple task:
result = 0
for i in range(n):
for j in range(n - a * i):
s = n - a * i - b * j - 1
if s >= 0:
result += s // c + 1
The following code prints the pythagorean triplet if it is equal to the input, but the problem is that it takes a long time for large numbers like 90,000 to answer.
What can I do to optimize the following code?
1 ≤ n ≤ 90 000
def pythagoreanTriplet(n):
# Considering triplets in
# sorted order. The value
# of first element in sorted
# triplet can be at-most n/3.
for i in range(1, int(n / 3) + 1):
# The value of second element
# must be less than equal to n/2
for j in range(i + 1,
int(n / 2) + 1):
k = n - i - j
if (i * i + j * j == k * k):
print(i, ", ", j, ", ",
k, sep="")
return
print("Impossible")
# Driver Code
vorodi = int(input())
pythagoreanTriplet(vorodi)
Your source code does a brute force search for a solution so it's slow.
Faster Code
def solve_pythagorean_triplets(n):
" Solves for triplets whose sum equals n "
solutions = []
for a in range(1, n):
denom = 2*(n-a)
num = 2*a**2 + n**2 - 2*n*a
if denom > 0 and num % denom == 0:
c = num // denom
b = n - a - c
if b > a:
solutions.append((a, b, c))
return solutions
OP code
Modified OP code so it returns all solutions rather than printing the first found to compare performance
def pythagoreanTriplet(n):
# Considering triplets in
# sorted order. The value
# of first element in sorted
# triplet can be at-most n/3.
results = []
for i in range(1, int(n / 3) + 1):
# The value of second element
# must be less than equal to n/2
for j in range(i + 1,
int(n / 2) + 1):
k = n - i - j
if (i * i + j * j == k * k):
results.append((i, j, k))
return results
Timing
n pythagoreanTriplet (OP Code) solve_pythagorean_triplets (new)
900 0.084 seconds 0.039 seconds
5000 3.130 seconds 0.012 seconds
90000 Timed out after several minutes 0.430 seconds
Explanation
Function solve_pythagorean_triplets is O(n) algorithm that works as follows.
Searching for:
a^2 + b^2 = c^2 (triplet)
a + b + c = n (sum equals input)
Solve by searching over a (i.e. a fixed for an iteration). With a fixed, we have two equations and two unknowns (b, c):
b + c = n - a
c^2 - b^2 = a^2
Solution is:
denom = 2*(n-a)
num = 2*a**2 + n**2 - 2*n*a
if denom > 0 and num % denom == 0:
c = num // denom
b = n - a - c
if b > a:
(a, b, c) # is a solution
Iterate a range(1, n) to get different solutions
Edit June 2022 by #AbhijitSarkar:
For those who like to see the missing steps:
c^2 - b^2 = a^2
b + c = n - a
=> b = n - a - c
c^2 - (n - a - c)^2 = a^2
=> c^2 - (n - a - c) * (n - a - c) = a^2
=> c^2 - n(n - a - c) + a(n - a - c) + c(n - a - c) = a^2
=> c^2 - n^2 + an + nc + an - a^2 - ac + cn - ac - c^2 = a^2
=> -n^2 + 2an + 2nc - a^2 - 2ac = a^2
=> -n^2 + 2an + 2nc - 2a^2 - 2ac = 0
=> 2c(n - a) = n^2 - 2an + 2a^2
=> c = (n^2 - 2an + 2a^2) / 2(n - a)
DarrylG's answer is correct, and I've added the missing steps to it as well, but there's another solution that's faster than iterating from [1, n). Let me explain it, but I'll leave the code up to the reader.
We use Euclid's formula of generating a tuple.
a = m^2 - n^2, b = 2mn, c = m^2 + n^2, where m > n > 0 ---(i)
a + b + c = P ---(ii)
Combining equations (i) and (ii), we have:
2m^2 + 2mn = P ---(iii)
Since m > n > 0, 1 <= n <= m - 1.
Putting n=1 in equation (iii), we have:
2m^2 + 2m - P = 0, ax^2 + bx + c = 0, a=2, b=2, c=-P
m = (-b +- sqrt(b^2 - 4ac)) / 2a
=> (-2 +- sqrt(4 + 8P)) / 4
=> (-1 +- sqrt(1 + 2P)) / 2
Since m > 0, sqrt(b^2 - 4ac) > -b, the only solution is
(-1 + sqrt(1 + 2P)) / 2 ---(iv)
Putting n=m-1 in equation (iii), we have:
2m^2 + 2m(m - 1) - P = 0
=> 4m^2 - 2m - P = 0, ax^2 + bx + c = 0, a=4, b=-2, c=-P
m = (-b +- sqrt(b^2 - 4ac)) / 2a
=> (2 +- sqrt(4 + 16P)) / 8
=> (1 +- sqrt(1 + 4P)) / 4
Since m > 0, the only solution is
(1 + sqrt(1 + 4P)) / 4 ---(v)
From equation (iii), m^2 + mn = P/2; since P/2 is constant,
when n is the smallest, m must be the largest, and vice versa.
Thus:
(1 + sqrt(1 + 4P)) / 4 <= m <= (-1 + sqrt(1 + 2P)) / 2 ---(vi)
Solving equation (iii) for n, we have:
n = (P - 2m^2) / 2m ---(vii)
We iterate for m within the bounds given by the inequality (vi)
and check when the corresponding n given by equation (vii) is
an integer.
Despite generating all primitive triples, Euclid's formula does not
produce all triples - for example, (9, 12, 15) cannot be generated using
integer m and n. This can be remedied by inserting an additional
parameter k to the formula. The following will generate all Pythagorean
triples uniquely.
a = k(m^2 - n^2), b = 2kmn, c = k(m^2 + n^2), for k >= 1.
Thus, we iterate for integer values of P/k until P < 12,
lowest possible perimeter corresponding to the triple (3, 4, 5).
Yo
I don't know if you still need the answer or not but hopefully, this can help.
n = int(input())
ans = [(a, b, c) for a in range(1, n) for b in range(a, n) for c in range(b, n) if (a**2 + b**2 == c**2 and a + b + c == n)]
if ans:
print(ans[0][0], ans[0][1], ans[0][2])
else:
print("Impossible")
I have a function that is defined in this way:
F(n) = n if n<=3
F(n) = F(n-1) + 2 * F(n-2) + 3 * F(n-3) if n>3
Now, I've written it as a recursive function and it works fine.
I'm trying to write it as an iterative function but i cant seem to make it happen.
The output should be, for example:
print(FRec(5)) => 22
print(FRec(10)) => 1657
print(FRec(15)) => 124905
Any tips?
Here is my recursive implementation:
def FRec(n):
if(n <= 3):
return n
if(n > 3):
return FRec(n - 1) + 2 * FRec(n - 2) + 3 * FRec(n - 3)
All you need is keep the last 3 results:
from collections import deque
def F_iter(n):
if n <= 3:
return n
prev = deque([1, 2, 3], maxlen=3)
for i in range(4, n + 1):
result = prev[-1] + 2 * prev[-2] + 3 * prev[-3]
prev.append(result)
return prev[-1]
If a deque is not 'available' to you, then you can inefficiently replace that with some list slicing and concatenation:
prev = [1, 2, 3]
for i in range(4, n + 1):
result = prev[-1] + 2 * prev[-2] + 3 * prev[-3]
prev = prev[1:] + [result]
Demo:
>>> F_iter(5)
22
>>> F_iter(10)
1657
>>> F_iter(15)
124905