giulio98/xlcost-single-prompt huggingface dataset:
# color n boxes using m colors such that k boxes have different color from the box on its left | python3 program to paint n boxes using m colors such that k boxes have color different from color of box on its left ; this function returns the required number of ways where idx is the current index and diff is number of boxes having different color from box on its left ; base case ; if already computed ; either paint with same color as previous one ; or paint with remaining ( m - 1 ) colors ; 

M = 1001
MOD = 998244353
dp = [[-1] * M] * M


def solve(idx, diff, N, M, K):
    if (idx > N):
        if (diff == K):
            return 1
        return 0
    if (dp[idx][diff] != -1):
        return dp[idx]
    ans = solve(idx + 1, diff, N, M, K)
    ans += (M - 1) * solve(idx + 1, diff + 1, N, M, K)
    dp[idx][diff] = ans % MOD
    return dp[idx][diff]


if __name__ == "__main__":
    N = 3
    M = 3
    K = 0
    print(M * solve(2, 0, N, M, K))

# Expected output:
3
# maximum path sum in an inverted triangle | set 2 | python program implementation of max sum problem in a triangle ; function for finding maximum sum ; loop for bottom - up calculation ; for each element , check both elements just below the number and below left to the number add the maximum of them to it ; return the maximum sum ; 

N = 3


def maxPathSum(tri):
    ans = 0
    for i in range(N - 2, -1, -1):
        for j in range(0, N - i):
            if (j - 1 >= 0):
                tri[i][j] += max(tri[i + 1][j], tri[i + 1][j - 1])
            else:
                tri[i][j] += tri[i + 1][j]
            ans = max(ans, tri[i][j])
    return ans


tri = [[1, 5, 3], [4, 8, 0], [1, 0, 0]]
print(maxPathSum(tri))

# Expected output:
14
# count no . of ordered subsets having a particular xor value | python 3 implementation of the approach ; returns count of ordered subsets of arr [ ] with xor value = k ; find maximum element in arr [ ] ; maximum possible xor value ; the value of dp [ i ] [ j ] [ k ] is the number of subsets of length k having xor of their elements as j from the set arr [ 0. . . i - 1 ] ; initializing all the values of dp [ i ] [ j ] [ k ] as 0 ; the xor of empty subset is 0 ; fill the dp table ; the answer is the number of subsets of all lengths from set arr [ 0. . n - 1 ] having xor of elements as k ; 

from math import log2


def subsetXOR(arr, n, K):
    max_ele = arr[0]
    for i in range(1, n):
        if (arr[i] > max_ele):
            max_ele = arr[i]
    m = (1 << int(log2(max_ele) + 1)) - 1
    dp = [[[0 for i in range(n + 1)]for j in range(m + 1)]
          for k in range(n + 1)]
    for i in range(n + 1):
        for j in range(m + 1):
            for k in range(n + 1):
                dp[i][j][k] = 0
    for i in range(n + 1):
        dp[i][0][0] = 1
    for i in range(1, n + 1):
        for j in range(m + 1):
            for k in range(n + 1):
                dp[i][j][k] = dp[i - 1][j][k]
                if (k != 0):
                    dp[i][j][k] += k * dp[i - 1][j ^ arr[i - 1]][k - 1]
    ans = 0
    for i in range(1, n + 1):
        ans += dp[n][K][i]
    return ans


if __name__ == '__main__':
    arr = [1, 2, 3]
    k = 1
    n = len(arr)
    print(subsetXOR(arr, n, k))

# Expected output:
3
# possible cuts of a number such that maximum parts are divisible by 3 | python3 program to find the maximum number of numbers divisible by 3 in a large number ; this will contain the count of the splits ; this will keep sum of all successive integers , when they are indivisible by 3 ; this is the condition of finding a split ; 
def get_max_splits(num_string):
    count = 0
    running_sum = 0
    for i in range(len(num_string)):
        current_num = int(num_string[i])
        running_sum += current_num
        if current_num % 3 == 0 or (running_sum != 0 and running_sum % 3 == 0):
            count += 1
            running_sum = 0
    return count


print(get_max_splits("12345"))

# Expected output:
3
# count of numbers in a range where digit d occurs exactly k times | python program to find the count of numbers in a range where digit d occurs exactly k times ; states - position , count , tight , nonz ; d is required digit and k is occurrence ; this function returns the count of required numbers from 0 to num ; last position ; if this result is already computed simply return it ; maximum limit upto which we can place digit . if tight is 1 , means number has already become smaller so we can place any digit , otherwise num [ pos ] ; nonz is true if we placed a non zero digit at the starting of the number ; at this position , number becomes smaller ; next recursive call , also set nonz to 1 if current digit is non zero ; function to convert x into its digit vector and uses count ( ) function to return the required count ; initialize dp ; 

M = 20
dp = []
d, K = None, None


def count(pos, cnt, tight, nonz, num: list):
    if pos == len(num):
        if cnt == K:
            return 1
        return 0
    if dp[pos][cnt][tight][nonz] != -1:
        return dp[pos][cnt][tight][nonz]
    ans = 0
    limit = 9 if tight else num[pos]
    for dig in range(limit + 1):
        currCnt = cnt
        if dig == d:
            if d != 0 or not d and nonz:
                currCnt += 1
        currTight = tight
        if dig < num[pos]:
            currTight = 1
        ans += count(pos + 1, currCnt, currTight, (nonz or dig != 0), num)
    dp[pos][cnt][tight][nonz] = ans
    return dp[pos][cnt][tight][nonz]


def solve(x):
    global dp, K, d
    num = []
    while x:
        num .append(x % 10)
        x //= 10
    num .reverse()
    dp = [[[[-1, -1]for i in range(2)]for j in range(M)]for k in range(M)]
    return count(0, 0, 0, 0, num)


if __name__ == "__main__":
    L = 11
    R = 100
    d = 2
    K = 1
    print(solve(R) - solve(L - 1))

# Expected output:
17
# count of numbers in range where first digit is equal to last digit of the number | python3 program to implement the above approach ; base case ; calculating the last digit ; calculating the first digit ; 
def solve(x):
    ans, temp = 0, x
    if (x < 10):
        return x
    last = x % 10
    while (x):
        first = x % 10
        x = x // 10
    if (first <= last):
        ans = 9 + temp // 10
    else:
        ans = 8 + temp // 10
    return ans


L, R = 2, 60
print(solve(R) - solve(L - 1))
L, R = 1, 1000
print(solve(R) - solve(L - 1))

# Expected output:
13
108
# form n | function returns the minimum cost to form a n - copy string here , x -> cost to add / remove a single character ' g ' and y -> cost to append the string to itself ; base case : ro form a 1 - copy string we need tp perform an operation of type 1 ( i , e add ) ; case1 . perform a add operation on ( i - 1 ) copy string case2 . perform a type 2 operation on ( ( i + 1 ) / 2 ) - copy string ; case1 . perform a add operation on ( i - 1 ) - copy string case2 . perform a type operation on ( i / 2 ) - copy string ; 
def findMinimumCost(n, x, y):
    dp = [0 for i in range(n + 1)]
    dp[1] = x
    for i in range(2, n + 1):
        if i & 1:
            dp[i] = min(dp[i - 1] + x, dp[(i + 1) // 2] + y + x)
        else:
            dp[i] = min(dp[i - 1] + x, dp[i // 2] + y)
    return dp[n]


n, x, y = 4, 2, 1
print(findMinimumCost(n, x, y))

# Expected output:
4
# minimum steps to reach any of the boundary edges of a matrix | set 1 | python program to find minimum steps to reach any of the boundary edges of a matrix ; function to find out minimum steps ; boundary edges reached ; already had a route through this point , hence no need to re - visit ; visiting a position ; vertically up ; horizontally right ; horizontally left ; vertically down ; minimum of every path ; function that returns the minimum steps ; index to store the location at which you are standing ; find '2' in the matrix ; initialize dp matrix with - 1 ; initialize vis matrix with false ; call function to find out minimum steps using memoization and recursion ; if not possible ; 

r = 4
col = 5


def findMinSteps(mat, n, m, dp, vis):
    if (n == 0 or m == 0 or n == (r - 1) or m == (col - 1)):
        return 0
    if (dp[n][m] != -1):
        return dp[n][m]
    vis[n][m] = True
    ans1, ans2, ans3, ans4 = 10 ** 9, 10 ** 9, 10 ** 9, 10 ** 9
    if (mat[n - 1][m] == 0):
        if (vis[n - 1][m] == False):
            ans1 = 1 + findMinSteps(mat, n - 1, m, dp, vis)
    if (mat[n][m + 1] == 0):
        if (vis[n][m + 1] == False):
            ans2 = 1 + findMinSteps(mat, n, m + 1, dp, vis)
    if (mat[n][m - 1] == 0):
        if (vis[n][m - 1] == False):
            ans3 = 1 + findMinSteps(mat, n, m - 1, dp, vis)
    if (mat[n + 1][m] == 0):
        if (vis[n + 1][m] == False):
            ans4 = 1 + findMinSteps(mat, n + 1, m, dp, vis)
    dp[n][m] = min(ans1, min(ans2, min(ans3, ans4)))
    return dp[n][m]


def minimumSteps(mat, n, m):
    twox = -1
    twoy = -1
    for i in range(n):
        for j in range(m):
            if (mat[i][j] == 2):
                twox = i
                twoy = j
                break
        if (twox != -1):
            break
    dp = [[-1 for i in range(col)]for i in range(r)]
    vis = [[False for i in range(col)]for i in range(r)]
    res = findMinSteps(mat, twox, twoy, dp, vis)
    if (res >= 10 ** 9):
        return -1
    else:
        return res


mat = [[1, 1, 1, 0, 1], [1, 0, 2, 0, 1], [0, 0, 1, 0, 1], [1, 0, 1, 1, 0]]
print(minimumSteps(mat, r, col))

# Expected output:
2
# count the number of special permutations | function to return the number of ways to chooser objects out of n objects ; function to return the number of degrangemnets of n ; function to return the required number of permutations ; ways to chose i indices from n indices ; dearrangements of ( n - i ) indices ; 
def nCr(n, r):
    ans = 1
    if r > n - r:
        r = n - r
    for i in range(r):
        ans *= (n - i)
        ans /= (i + 1)
    return ans


def countDerangements(n):
    der = [0 for i in range(n + 3)]
    der[0] = 1
    der[1] = 0
    der[2] = 1
    for i in range(3, n + 1):
        der[i] = (i - 1) * (der[i - 1] + der[i - 2])
    return der[n]


def countPermutations(n, k):
    ans = 0
    for i in range(n - k, n + 1):
        ways = nCr(n, i)
        ans += ways * countDerangements(n - i)
    return ans


n, k = 5, 3
print(countPermutations(n, k))

# Expected output:
31.0
# ways to place k bishops on an nã — n chessboard so that no two attack | returns the number of squares in diagonal i ; returns the number of ways to fill a n * n chessboard with k bishops so that no two bishops attack each other . ; return 0 if the number of valid places to be filled is less than the number of bishops ; dp table to store the values ; setting the base conditions ; calculate the required number of ways ; stores the answer ; 
def squares(i):
    if ((i & 1) == 1):
        return int(i / 4) * 2 + 1
    else:
        return int((i - 1) / 4) * 2 + 2


def bishop_placements(n, k):
    if (k > 2 * n - 1):
        return 0
    dp = [[0 for i in range(k + 1)]for i in range(n * 2)]
    for i in range(n * 2):
        dp[i][0] = 1
    dp[1][1] = 1
    for i in range(2, n * 2, 1):
        for j in range(1, k + 1, 1):
            dp[i][j] = (dp[i - 2][j] + dp[i - 2][j - 1] * (squares(i) - j + 1))
    ans = 0
    for i in range(0, k + 1, 1):
        ans += (dp[n * 2 - 1][i] * dp[n * 2 - 2][k - i])
    return ans


if __name__ == '__main__':
    n = 2
    k = 2
    ans = bishop_placements(n, k)
    print(ans)

# Expected output:
4
# number of ways to partition a string into two balanced subsequences | for maximum length of input string ; declaring the dp table ; declaring the prefix array ; function to calculate the number of valid assignments ; return 1 if x is balanced . ; increment the count if it is an opening bracket ; decrement the count if it is a closing bracket ; 

MAX = 10
F = [[-1 for i in range(MAX)]for j in range(MAX)]
C = [None] * MAX


def noOfAssignments(S, n, i, c_x):
    if F[i][c_x] != -1:
        return F[i][c_x]
    if i == n:
        F[i][c_x] = not c_x
        return F[i][c_x]
    c_y = C[i] - c_x
    if S[i] == '(':
        F[i][c_x] = noOfAssignments(
            S, n, i + 1, c_x + 1) + noOfAssignments(S, n, i + 1, c_x)
        return F[i][c_x]
    F[i][c_x] = 0
    if c_x:
        F[i][c_x] += noOfAssignments(S, n, i + 1, c_x - 1)
    if c_y:
        F[i][c_x] += noOfAssignments(S, n, i + 1, c_x)
    return F[i][c_x]


if __name__ == "__main__":
    S = "()"
    n = len(S)
    C[0] = 0
    for i in range(0, n):
        if S[i] == '(':
            C[i + 1] = C[i] + 1
        else:
            C[i + 1] = C[i] - 1
    print(noOfAssignments(S, n, 0, 0))

# Expected output:
2
# minimum sum falling path in a nxn grid | python3 program to minimum required sum ; function to return minimum path falling sum ; r = row and c = column we begin from second last row and keep adding maximum sum . ; best = min ( a [ r + 1 ] [ c - 1 ] , a [ r + 1 ] [ c ] , a [ r + 1 ] [ c + 1 ] ) ; 

import sys
n = 3


def minFallingPathSum(A):
    for R in range(n - 2, -1, -1):
        for C in range(n):
            best = A[R + 1][C]
            if C > 0:
                best = min(best, A[R + 1][C - 1])
            if C + 1 < n:
                best = min(best, A[R + 1][C + 1])
            A[R][C] = A[R][C] + best
    ans = sys .maxsize
    for i in range(n):
        ans = min(ans, A[0][i])
    return ans


if __name__ == "__main__":
    A = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
    print(minFallingPathSum(A))

# Expected output:
12
# find the maximum sum of plus shape pattern in a 2 | python 3 program to find the maximum value of a + shaped pattern in 2 - d array ; function to return maximum plus value ; initializing answer with the minimum value ; initializing all four arrays ; initializing left and up array . ; initializing right and down array . ; calculating value of maximum plus ( + ) sign ; 

N = 100
n = 3
m = 4


def maxPlus(arr):
    ans = 0
    left = [[0 for x in range(N)]for y in range(N)]
    right = [[0 for x in range(N)]for y in range(N)]
    up = [[0 for x in range(N)]for y in range(N)]
    down = [[0 for x in range(N)]for y in range(N)]
    for i in range(n):
        for j in range(m):
            left[i][j] = (max(0, (left[i][j - 1]if j else 0)) + arr[i][j])
            up[i][j] = (max(0, (up[i - 1][j]if i else 0)) + arr[i][j])
    for i in range(n):
        for j in range(m):
            right[i][j] = max(
                0, (0 if (j + 1 == m)else right[i][j + 1])) + arr[i][j]
            down[i][j] = max(
                0, (0 if (i + 1 == n)else down[i + 1][j])) + arr[i][j]
    for i in range(1, n - 1):
        for j in range(1, m - 1):
            ans = max(ans, up[i - 1][j] + down[i + 1][j] +
                      left[i][j - 1] + right[i][j + 1] + arr[i][j])
    return ans


if __name__ == "__main__":
    arr = [[1, 1, 1, 1], [-6, 1, 1, -4], [1, 1, 1, 1]]
    print(maxPlus(arr))

# Expected output:
0
# total number of different staircase that can made from n boxes | function to find the total number of different staircase that can made from n boxes ; dp table , there are two states . first describes the number of boxes and second describes the step ; initialize all the elements of the table to zero ; base case ; when step is equal to 2 ; when step is greater than 2 ; count the total staircase from all the steps ; 
def countStaircases(N):
    memo = [[0 for x in range(N + 5)]for y in range(N + 5)]
    for i in range(N + 1):
        for j in range(N + 1):
            memo[i][j] = 0
    memo[3][2] = memo[4][2] = 1
    for i in range(5, N + 1):
        for j in range(2, i + 1):
            if (j == 2):
                memo[i][j] = memo[i - j][j] + 1
            else:
                memo[i][j] = (memo[i - j][j] + memo[i - j][j - 1])
    answer = 0
    for i in range(1, N + 1):
        answer = answer + memo[N][i]
    return answer


if __name__ == "__main__":
    N = 7
    print(countStaircases(N))

# Expected output:
4
# find maximum points which can be obtained by deleting elements from array | function to return maximum cost obtained ; find maximum element of the array . ; create and initialize count of all elements to zero . ; calculate frequency of all elements of array . ; stores cost of deleted elements . ; selecting minimum range from l and r . ; finds upto which elements are to be deleted when element num is selected . ; get maximum when selecting element num or not . ; 
def maxCost(a, n, l, r):
    mx = 0
    for i in range(n):
        mx = max(mx, a[i])
    count = [0] * (mx + 1)
    for i in range(n):
        count[a[i]] += 1
    res = [0] * (mx + 1)
    res[0] = 0
    l = min(l, r)
    for num in range(1, mx + 1):
        k = max(num - l - 1, 0)
        res[num] = max(res[num - 1], num * count[num] + res[k])
    return res[mx]


if __name__ == "__main__":
    a = [2, 1, 2, 3, 2, 2, 1]
    l, r = 1, 1
    n = len(a)
    print(maxCost(a, n, l, r))

# Expected output:
8
# count the number of ways to traverse a matrix | returns the number of way from top - left to mat [ m - 1 ] [ n - 1 ] ; return 1 if it is the first row or first column ; recursively find the no of way to reach the last cell . ; 
def countPaths(m, n):
    if m == 1 or n == 1:
        return 1
    return (countPaths(m - 1, n) + countPaths(m, n - 1))


if __name__ == "__main__":
    n = 5
    m = 5
    print(countPaths(n, m))

# Expected output:
70
# count the number of ways to traverse a matrix | returns the number of way from top - left to mat [ m - 1 ] [ n - 1 ] ; 
def countPaths(m, n):
    dp = [[0 for i in range(m + 1)]for j in range(n + 1)]
    for i in range(1, m + 1):
        for j in range(1, n + 1):
            if (i == 1 or j == 1):
                dp[i][j] = 1
            else:
                dp[i][j] = (dp[i - 1][j] + dp[i][j - 1])
    return dp[m][n]


if __name__ == "__main__":
    n = 5
    m = 5
    print(countPaths(n, m))

# Expected output:
70
# minimum number of palindromes required to express n as a sum | set 1 | declaring the dp table as global variable ; a utility for creating palindrome ; checks if number of digits is odd or even if odd then neglect the last digit of input in finding reverse as in case of odd number of digits middle element occur once ; creates palindrome by just appending reverse of number to itself ; function to generate palindromes ; run two times for odd and even length palindromes ; creates palindrome numbers with first half as i . value of j decides whether we need an odd length or even length palindrome . ; function to find the minimum number of elements in a sorted array a [ i . . j ] such that their sum is n ; function to find the minimum number of palindromes that n can be expressed as a sum of ; getting the list of all palindromes upto n ; sorting the list of palindromes ; returning the required value ; 

dp = [[0 for i in range(1000)]for i in range(1000)]


def createPalindrome(input, isOdd):
    n = input
    palin = input
    if (isOdd):
        n //= 10
    while (n > 0):
        palin = palin * 10 + (n % 10)
        n //= 10
    return palin


def generatePalindromes(N):
    palindromes = []
    number = 0
    for j in range(2):
        i = 1
        number = createPalindrome(i, j)
        while number <= N:
            number = createPalindrome(i, j)
            palindromes .append(number)
            i += 1
    return palindromes


def minimumSubsetSize(A, i, j, N):
    if (not N):
        return 0
    if (i > j or A[i] > N):
        return 10 ** 9
    if (dp[i][N]):
        return dp[i][N]
    dp[i][N] = min(
        1 +
        minimumSubsetSize(
            A,
            i +
            1,
            j,
            N -
            A[i]),
        minimumSubsetSize(
            A,
            i +
            1,
            j,
            N))
    return dp[i][N]


def minimumNoOfPalindromes(N):
    palindromes = generatePalindromes(N)
    palindromes = sorted(palindromes)
    return minimumSubsetSize(palindromes, 0, len(palindromes) - 1, N)


N = 65
print(minimumNoOfPalindromes(N))

# Expected output:
3
# number of ways a convex polygon of n + 2 sides can split into triangles by connecting vertices | returns value of binomial coefficient c ( n , k ) ; since c ( n , k ) = c ( n , n - k ) ; calculate value of [ n * ( n - 1 ) * -- - * ( n - k + 1 ) ] / [ k * ( k - 1 ) * -- - * 1 ] ; a binomial coefficient based function to find nth catalan number in o ( n ) time ; calculate value of 2 ncn ; return 2 ncn / ( n + 1 ) ; 
def binomialCoeff(n, k):
    res = 1
    if (k > n - k):
        k = n - k
    for i in range(k):
        res *= (n - i)
        res /= (i + 1)
    return res


def catalan(n):
    c = binomialCoeff(2 * n, n)
    return int(c / (n + 1))


n = 3
print(catalan(n))

# Expected output:
5
# alternate fibonacci numbers | alternate fibonacci series using dynamic programming ; 0 th and 1 st number of the series are 0 and 1 ; 
def alternateFib(n):
    if (n < 0):
        return -1
    f1 = 0
    f2 = 1
    print(f1, end=" ")
    for i in range(2, n + 1):
        f3 = f2 + f1
        if (i % 2 == 0):
            print(f3, end=" ")
        f1 = f2
        f2 = f3


N = 15
alternateFib(N)

# Expected output:
0 1 3 8 21 55 144 377
# number of ways to form an array with distinct adjacent elements | returns the total ways to form arrays such that every consecutive element is different and each element except the first and last can take values from 1 to m ; define the dp [ ] [ ] array ; if the first element is 1 ; there is only one way to place a 1 at the first index ; the value at first index needs to be 1 , thus there is no way to place a non - one integer ; if the first element was 1 then at index 1 , only non one integer can be placed thus there are m - 1 ways to place a non one integer at index 2 and 0 ways to place a 1 at the 2 nd index ; else there is one way to place a one at index 2 and if a non one needs to be placed here , there are ( m - 2 ) options , i . e neither the element at this index should be 1 , neither should it be equal to the previous element ; build the dp array in bottom up manner ; f ( i , one ) = f ( i - 1 , non - one ) ; f ( i , non - one ) = f ( i - 1 , one ) * ( m - 1 ) + f ( i - 1 , non - one ) * ( m - 2 ) ; last element needs to be one , so return dp [ n - 1 ] [ 0 ] ; 
def totalWays(N, M, X):
    dp = [[0 for i in range(2)]for j in range(N + 1)]
    if (X == 1):
        dp[0][0] = 1
    else:
        dp[0][1] = 0
    if (X == 1):
        dp[1][0] = 0
        dp[1][1] = M - 1
    else:
        dp[1][0] = 1
        dp[1][1] = (M - 2)
    for i in range(2, N):
        dp[i][0] = dp[i - 1][1]
        dp[i][1] = dp[i - 1][0] * (M - 1) + dp[i - 1][1] * (M - 2)
    return dp[N - 1][0]


if __name__ == '__main__':
    N = 4
    M = 3
    X = 2
    print(totalWays(N, M, X))

# Expected output:
3
# memoization ( 1d , 2d and 3d ) | fibonacci series using recursion ; base case ; recursive calls ; 
def fib(n):
    if (n <= 1):
        return n
    return fib(n - 1) + fib(n - 2)


if __name__ == '__main__':
    n = 6
    print(fib(n))

# Expected output:
8
# memoization ( 1d , 2d and 3d ) | python program to find the nth term of fibonacci series ; fibonacci series using memoized recursion ; base case ; if fib ( n ) has already been computed we do not do further recursive calls and hence reduce the number of repeated work ; store the computed value of fib ( n ) in an array term at index n to so that it does not needs to be precomputed again ; 

term = [0 for i in range(1000)]


def fib(n):
    if n <= 1:
        return n
    if term[n] != 0:
        return term[n]
    else:
        term[n] = fib(n - 1) + fib(n - 2)
        return term[n]


n = 6
print(fib(n))

# Expected output:
8
# memoization ( 1d , 2d and 3d ) | returns length of lcs for x [ 0. . m - 1 ] , y [ 0. . n - 1 ] ; 
def lcs(X, Y, m, n):
    if (m == 0 or n == 0):
        return 0
    if (X[m - 1] == Y[n - 1]):
        return 1 + lcs(X, Y, m - 1, n - 1)
    else:
        return max(lcs(X, Y, m, n - 1), lcs(X, Y, m - 1, n))


if __name__ == '__main__':
    X = "AGGTAB"
    Y = "GXTXAYB"
    m = len(X)
    n = len(Y)
    print("Length of LCS is {}n".format(lcs(X, Y, m, n)))

# Expected output:
Length of LCS is 4n