Добрый вечер. Решаю задачу 
тутВернуть True если слово возможно составить из слов списка-словаря, False - если нет. Одно и то же слово из словаря может быть использовано много раз, а ещё такое слово может быть подстрокой другого слова
За два дня я разработал решение способное случайно проскочить комплект тестов, но примерно в одном случае из ста оно может дать ложноположительный результат. Идея такая, преобразовать строки словаря-списка так, чтобы ни одна из них не начиналась ни с одной другой из них, а потом уже "раздевать" слово используя этот новый список. Но строки в новом списке получаются более короткими и из них возможно составить слово которое невозможно составить из строк оригинального списка
Вот код:
def new_seq(seq):
    new = seq[:]
    for el in seq:
        for i in range(len(new)):
            while new[i] != el and new[i].startswith(el):
                new[i] = new[i].replace(el, '', 1)
    while '' in new:
        new.remove('')
    if new != seq:
        return new_seq(new)
    return new
def new_word(word, seq):
    new = word
    for w in seq:
        while new.startswith(w):
            new = new.replace(w, '', 1)
    if new != word:
        return new_word(new, seq)
    return new
def valid_word(seq, word):
    seq = list(set(seq))
    seq = new_seq(seq)
    print(seq)
    word = new_word(word, seq)
    return not word
seq = ['cy', 'fczdqcy', 'hzjkfczd', 'hfc', 'h', 'hh', 'fczdqfczd', 'cyh', 'cyhzjk', 'mfcz', 'fczdq', 'cyfcz',
       'fczdqcy', 'cycy']
word = 'cyhhhfczdqcyhzjkfczdqfczdqcycyfczdqcymfczdq'
print(valid_word(seq, word))  # False
 
  Проблема кажется мне неустранимой. Поэтому я ищу другие подходы. Например думаю над таким: программа должна искать способ построить слово из имеющихся слогов, но если она заходит в тупик, то возвращаться обратно. Для этой цели я даже придумал оригинальный тест (первая версия программы его кстати успешно проходит):
seq = ['abcd', 'abcdd', 'abcdddd', 'ddddefg', 'defg', 'ddfgh', 'ddfghh', 'ddfghhhh', 'hhhhijk', 'hhijk', 'hijk']
word = 'abcddddefghhhhijk'
print(valid_word(seq, word))  # True
 
Тут слово возможно составить только из трёх слогов:  'abcdd', 'ddfghh', 'hhijk'
Третий уже очевиден если найдены первые два. А вот с первыми двумя всё не так просто. Простая "правильная" сортировка списка слов тут не поможет, так как оба раза выбирать надо не самый короткий или самый длинный слог, а средний по длине. И возможны такие ситуации, когда в одном случае (одна первая буква слога) надо выбрать самый длинный слог (или длиннее среднего), а в другом (другая первая буква) - самый короткий (или короче среднего). Я пытался в словаре сохранять эдакое "дерево вариантов" ключ - слог, от которого избавлялось слово, значение - новое слово, когда все такие ключи закончились: ключ - двухэлементный кортеж, второй элемент - второй слог от которого избавлялось слово ранее избавленное от первого, потом уже ключи из трёхэлементных кортежей - но путь показался мне тупиковым с вычислительной точки зрения, в худшем случае факториал (от количества разных слогов) возможных вариантов получается. Или даже хуже, нельзя за раз удалить все вхождения слога в строку, так как в одном месте может потребоваться удалить именно этот слог, а в другом слог частично с первым пересекающийся
UPD Хотя словарь с деревом вариантов и иначе можно строить. Например в приведённом примере слово можно начать раздевать лстрипить с трёх разных слогов, получится три разных ключа-значения, а потом обнаружить что только одно из этих значений можно ещё тремя разными способами лстрипнуть и только один вариант правильный. Но если например слово начинается с английского алфавита, а слоги: a, ab, abc, abcd, ... и так 26 слогов с последним длиной в английский алфавит, а потом ещё какие то?