diff --git a/dynamic_programming/all_construct.py b/dynamic_programming/all_construct.py new file mode 100644 index 000000000..5ffed2caa --- /dev/null +++ b/dynamic_programming/all_construct.py @@ -0,0 +1,58 @@ +""" +Program to list all the ways a target string can be +constructed from the given list of substrings +""" +from __future__ import annotations + + +def all_construct(target: str, word_bank: list[str] | None = None) -> list[list[str]]: + """ + returns the list containing all the possible + combinations a string(target) can be constructed from + the given list of substrings(word_bank) + >>> all_construct("hello", ["he", "l", "o"]) + [['he', 'l', 'l', 'o']] + >>> all_construct("purple",["purp","p","ur","le","purpl"]) + [['purp', 'le'], ['p', 'ur', 'p', 'le']] + """ + + word_bank = word_bank or [] + # create a table + table_size: int = len(target) + 1 + + table: list[list[list[str]]] = [] + for i in range(table_size): + table.append([]) + # seed value + table[0] = [[]] # because empty string has empty combination + + # iterate through the indices + for i in range(table_size): + # condition + if table[i] != []: + for word in word_bank: + # slice condition + if target[i : i + len(word)] == word: + new_combinations: list[list[str]] = [ + [word] + way for way in table[i] + ] + # adds the word to every combination the current position holds + # now,push that combination to the table[i+len(word)] + table[i + len(word)] += new_combinations + + # combinations are in reverse order so reverse for better output + for combination in table[len(target)]: + combination.reverse() + + return table[len(target)] + + +if __name__ == "__main__": + print(all_construct("jwajalapa", ["jwa", "j", "w", "a", "la", "lapa"])) + print(all_construct("rajamati", ["s", "raj", "amat", "raja", "ma", "i", "t"])) + print( + all_construct( + "hexagonosaurus", + ["h", "ex", "hex", "ag", "ago", "ru", "auru", "rus", "go", "no", "o", "s"], + ) + )