# AUTOGENERATED! DO NOT EDIT! File to edit: 12_core_subsequences.ipynb (unless otherwise specified).

__all__ = ['get_subsequences', 'get_ndistinct_subsequences']

# Cell
from itertools import combinations
def get_subsequences(sequence):
    subsequences = []
    for i in range(0, len(sequence)+1):
        temp = [list(x) for x in combinations(sequence, i)]
        if len(temp)>0:
            subsequences.extend(temp)
    return subsequences[1:]

# Cell
def get_ndistinct_subsequences(sequence):
    # this implementation works on strings, so parse non-strings to strings
    if sequence is not str:
        sequence = [str(e) for e in sequence]

    # create an array to store index of last
    last = [-1 for i in range(256 + 1)] # hard-coded value needs explaining -ojs

    # length of input string
    sequence_length = len(sequence)

    # dp[i] is going to store count of discount subsequence of length of i
    dp = [-2 for i in range(sequence_length + 1)]

    # empty substring has only one subseqence
    dp[0] = 1

    # Traverse through all lengths from 1 to n
    for i in range(1, sequence_length + 1):

        # number of subseqence with substring str[0...i-1]
        dp[i] = 2 * dp[i - 1]

        # if current character has appeared before, then remove all subseqences ending with previous occurrence.
        if last[ord(sequence[i - 1])] != -1:
            dp[i] = dp[i] - dp[last[ord(sequence[i - 1])]]

        last[ord(sequence[i - 1])] = i - 1

    return dp[sequence_length]