python programming help for equation - python

I am new to python and trying to learn some codes. This is my first programming attempt with python. I have a sequence S and a sequence T(which is also a relation of a couples recurrence relationship equation)where
Sn= 2S(n-1)+S(n-2)+4T(n-1)
and T=S(n-1)+T(n-1).
S0=1, S1=2, T0=0 AND T1=1.
How can i write a function that returns nth value of S and T sequence where the function takes n as a parameter and returns Sn,Tn as a tuple as result of calling the function?

Here are the recursive functions:
def T(n):
if n == 0:
return 0
if n == 1:
return 1
return S(n - 1) + T(n - 1)
def S(n):
if n == 0:
return 1
if n == 1:
return 2
return 2 * S(n - 1) + S(n - 2) + 4 * T(n - 1)
def tuple_func(n):
return(S(n), T(n))
Somewhere between n == 20 and n == 30 this becomes ridiculously slow, depending on your threshold for ridiculousness.
"For fun" I've converted the recursive functions to an iterative version. On my computer it can do up to n == 50,000 in about a second.
def tuple_func(n):
S = [1, 2]
T = [0, 1]
if n < 0:
return(None, None)
if 0 >= n < 2:
return(S[n], T[n])
for n in range(2, n + 1):
S.append(2 * S[n - 1] + S[n - 2] + 4 * T[n - 1])
T.append(S[n - 1] + T[n - 1])
return(S[n], T[n])

Related

improve recursion efficiency in python

def f(n):
if n == 1:
return 1
else:
return (1 / (n - 1)) * (f(n - 1) + (1 / f(n - 1)))
n = int(input())
print(str(round(f(n),2)))
It's been said that my code is not efficient enough since there are two f(n-1)s in the recursion.
How can I improve it ?
If you use python ≥ 3.8 you could use an assignment expression:
def f(n):
if n == 1:
return 1
else:
return (1/(n-1)) * ((F:=f(n-1)) + (1/F)) # (F:=…) gets evaluated as …
# and instantiates F
n = int(input())
print(str(round(f(n),2)))
def f(n):
if n == 1:
return 1
else:
return (1 / (n - 1)) * (f(n - 1) + (1 / f(n - 1)))
n = int(input())
print(str(round(f(n),2)))
#as long as n gets bigger
the function will turn into infinite loop
You can try this:
else:
def alternative(n):
s= (1 / (n - 1))
def altr(s):
return (n - 1) + (1 / (n - 1))

What's the difference between these two python programs?

I am solving a algorithm problem on LeetCode (5th problem if you want to read the problem first
https://leetcode.com/problems/longest-palindromic-substring/).
I wrote a python program:
class Solution(object):
def longestPalindrome(self, s):
"""
:type s: str
:rtype: str
"""
l = 1
if len(s) < 2:
return s
result = s[0]
for end in range(1, len(s)):
if end - (l + 1) >= 0 and s[end - (l + 1):end + 1] == s[end - (l + 1):end + 1][::-1]:
l += 2
result = s[end - (l + 1):end + 1]
continue
elif end - l >= 0 and s[end - l:end + 1] == s[end - l:end + 1][::-1]:
l += 1
result = s[end-l:end+1]
return result
When I test it using 'abba' as input: it outputs 'ba'.
Then, I found a python solution in the discussion, the program looks like this:
class Solution:
# #return a string
def longestPalindrome(self, s):
if len(s) == 0: return 0
maxLen = 1
start = 0
for i in xrange(len(s)):
if i - maxLen >= 1 and s[i - maxLen - 1:i + 1] == s[i - maxLen - 1:i + 1][::-1]:
start = i - maxLen - 1
maxLen += 2
continue
if i - maxLen >= 0 and s[i - maxLen:i + 1] == s[i - maxLen:i + 1][::-1]:
start = i - maxLen
maxLen += 1
return s[start:start + maxLen]
When I test it using 'abba' as input, it outputs 'abba' correctly.
I am a pretty new beginner in python, so I always get confused by the matter of passing parameters in python. So, could anyone tell me why the two python programs get two different results?
Thanks in advance.
You change l between where you determine there is a palindrome and where you use l to assign that palindrome to result. In both places.

How to copy only value not use reference, or what I should do with this inside list reference?

I have written Smith-Waterman like algorithm and it is leaking
Here is my leaking fragment of code:
for row in range(1, n + 1):
for col in range(1, m + 1):
left = table[row][col - 1] - 1
up = table[row - 1][col] - 1
upLeft = table[row - 1][col - 1] + s(seq1[col - 1], seq2[row - 1])
table[row][col] = max(left, up, upLeft)
The last line leaks.
How to copy only value not use reference, or what I should do with this inside list reference?
Other question is how to optimize this algorithm to use only 2 columns/rows, but it's not difficult probably. First I want to know why the code leaking.
Full code:
def smith_waterman(seq1, seq2):
"""
:rtype : float
:return: folat
:param seq1: list of 0,1,2
:param seq2: list of 0,1,2
"""
m = len(seq1)
n = len(seq2)
def s(a, b):
"""
:param a: 0,1,2
:param b: 0,1,2
:return: iteger
"""
c = a + b
if a == b:
return 2
elif c == 3:
return 1
elif c == 2:
return 2
else:
return -1
# create empty table
table = []
for i in range(n + 1):
table.append([])
for j in range(m + 1):
table[i].append(0)
for row in range(1, n + 1):
for col in range(1, m + 1):
left = table[row][col - 1] - 1
up = table[row - 1][col] - 1
upLeft = table[row - 1][col - 1] + s(seq1[col - 1], seq2[row - 1])
table[row][col] = max(left, up, upLeft)
return table[n][m]) / (n + m)
What do you mean with "leaking"? Are you referring to the fact that your algorithm uses more memory than expected? If this is the case, then it could be related to your table definition vs. its usage: you're allocating an n x m table, whereas you're using just (n-1) x (m-1) items.
Try changing your loops from range(1, n+1) to range(n), making the similar change for the second index (and updating the index usages of course).

Longest common substring

I am trying to create a program which will receive two strings and compeer between, and returns the largest common letters in the order they appear.
examples:
string1="a" string2="b"
return ""
string1="abc" string2="ac"
return "ac"
string1:“abcd” string2:“ acdbb”
return:“ abcd"
I need to write 3 codes - "normal way", recursive way and "in memorization" way.
So far I've succeed to code:
def l_c_s(s1, s2):
for i in range(1 + len(s1))]:
mi = [[0] * (1 + len(s2))
long, x_long = 0, 0
for x in range(1, 1 + len(s1)):
for y in range(1, 1 + len(s2)):
if s1[x - 1] == s2[y - 1]:
m[x][y] = m[x - 1][y - 1] + 1
if m[x][y] > long:
long = m[x][y]
x_long = x
m[x][y] = 0
return s1[x_long - long: x_long]
But I don't get what I wanted. just run this code for the string1="abc" string2="ac"
and the see what happens.
Moreover, I have no idea how to make it recursive and neither to write it in memo.
If what you want is really longest common sub-sequence, here is a version using memoization:
s1 = 'abcdd'
s2 = 'add'
mem = [[-1] * len(s2)] * len(s1)
matched = []
def lcs(i,j):
if i < 0 or j < 0:
return 0
if mem[i][j] >= 0:
return mem[i][j]
if s1[i] == s2[j]:
p = 1 + lcs(i-1, j-1)
if p > mem[i][j]:
mem[i][j] = p
matched.append(s1[i])
return max(mem[i][j], lcs(i-1, j), lcs(i, j-1))
lcs_length = lcs(len(s1)-1, len(s2)-1)
lcs = "".join(matched)
print 'LCS: <%s> of length %d' % (lcs, lcs_length)

Best style for maintaining long equation

What do you think is the best way of writing this method for calculating an ackermann function value? This function incorporates several 'short cuts' to the simplest method of calculating the value that speeds the calculation up considerably by reducing the amount of recursive calls, but you end up with a long expression.
The versions use:
The line continuation character \
Bracketed nested functions
A single outer set of braces
Does any version seem better to you? why? I'm curious.
>>> def ack4(M, N):
return (N + 1) if M == 0 else \
(N + 2) if M == 1 else \
(2*N + 3) if M == 2 else \
(8*(2**N - 1) + 5) if M == 3 else \
ack4(M-1, 1) if N == 0 else \
ack4(M-1, ack4(M, N-1))
>>> def ack2(M, N):
return (N + 1) if M == 0 else (
(N + 2) if M == 1 else (
(2*N + 3) if M == 2 else (
(8*(2**N - 1) + 5) if M == 3 else (
ack2(M-1, 1) if N == 0 else
ack2(M-1, ack2(M, N-1))))))
>>> def ack3(M, N):
return ((N + 1) if M == 0 else
(N + 2) if M == 1 else
(2*N + 3) if M == 2 else
(8*(2**N - 1) + 5) if M == 3 else
ack3(M-1, 1) if N == 0 else
ack3(M-1, ack3(M, N-1)))
>>> ack2(4, 2) == ack3(4, 2) == ack4(4, 2)
True
>>>
What's wrong with just nesting in a simple elif chain?
def ack5(m, n):
if m == 0:
return (n + 1)
elif m == 1:
return (n + 2)
elif m == 2:
return (2 * n + 3)
elif m == 3:
return (8 * ( 2 ** n - 1) + 5)
elif n == 0:
return ack5(m - 1, 1)
else:
return ack5(m - 1, ack5(m, n - 1))
Python code should be readable for the programmer, so it's more of a personal choice question. If I had to pick one of your 3 examples I'd go with ack4 since those backslashes indicate that everything is one big statement without bloating the expression like a bracket does in my opinion.
Don't be afraid of multiple returns. Also, try to avoid capital letters for local variables.
def ack4(m, n):
if m == 0:
return n + 1
if m == 1:
return n + 2
if m == 2:
return 2 * n + 3
if m == 3:
return (8 * ( 2 ** n - 1) + 5)
if n == 0:
return ack5(m - 1, 1)
return ack5(m - 1, ack5(m, n - 1))
def ack5(m, n):
if m == 0: return n + 1
if m == 1: return n + 2
if m == 2: return 2*n + 3
if m == 3: return 8*(2**n - 1) + 5
if n == 0: return ack5(m-1, 1)
return ack5(m-1, ack5(m, n-1))

Categories