Longest word chain from a list of words











up vote
16
down vote

favorite
5












So, this is a part of a function I'm trying to make.



I don't want the code to be too complicated.



I have a list of words, e.g.



words = ['giraffe', 'elephant', 'ant', 'tiger', 'racoon', 'cat', 'hedgehog', 'mouse']


The idea of the word chain sequence is for the next word to begin with the letter that the last word ended in.



(Edit: Each word cannot be used more than once. Other than that there are no other constraints.)



I want the output to give the longest word chain sequence, which in this case is:



['hedgehog', 'giraffe', 'elephant', 'tiger', 'racoon']


I'm not really sure how to do it, I had different attempts at trying this. One of them...



This code finds the word chain correctly if we start with a specific word from the list, e.g. words[0] (so 'giraffe'):



words = ['giraffe', 'elephant', 'ant', 'tiger', 'racoon', 'cat', 'hedgehog', 'mouse']

word_chain =

word_chain.append(words[0])

for word in words:
for char in word[0]:

if char == word_chain[-1][-1]:
word_chain.append(word)

print(word_chain)


Output:



['giraffe', 'elephant', 'tiger', 'racoon']


BUT, I want to find the longest possible chain of words (explained above).



My method: So, I tried to use the above working code that I wrote and loop through, using each word from the list as the starting point and finding the word chain for each word[0], word[1], word[2] etc. Then I tried to find the longest word chain by using an if statement and compare the length to the previous longest chain, but I can't get it done properly and I don't really know where this is going.



words = ['giraffe', 'elephant', 'ant', 'tiger', 'racoon', 'cat', 'hedgehog', 'mouse']

word_chain =
max_length = 0
for starting_word_index in range(len(words) - 1):

word_chain.append(words[starting_word_index])

for word in words:
for char in word[0]:

if char == word_chain[-1][-1]:
word_chain.append(word)

# Not sure

if len(word_chain) > max_length:
final_word_chain = word_chain
longest = len(word_chain)
word_chain.clear()

print(final_word_chain)


This is my nth attempt, I think this one prints an empty list, I had different attempts before this that failed to clear the word_chain list properly and ended up repeating words over again.



Any help much appreciated. Hopefully I didn't make this too teedious or confusing... Thanks!










share|improve this question









New contributor




Mandingo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.




















  • @dataLeo Hi, each word cannot be used more than once (so elephant can only be used once), no other constraints apart from that. Aim is to find the longest word chain sequence.
    – Mandingo
    11 hours ago












  • Do you need an added precaution in case someone slips in a name that start and ends with the same letter? (… not as if I can come up with one ...)
    – usr2564301
    10 hours ago










  • This would be a great contribution to codegolf.stackexchange.com
    – Frozenthia
    9 hours ago












  • This sounds like a problem for some graph theory. I'll take a look at it when I get home.
    – Mateen Ulhaq
    1 hour ago

















up vote
16
down vote

favorite
5












So, this is a part of a function I'm trying to make.



I don't want the code to be too complicated.



I have a list of words, e.g.



words = ['giraffe', 'elephant', 'ant', 'tiger', 'racoon', 'cat', 'hedgehog', 'mouse']


The idea of the word chain sequence is for the next word to begin with the letter that the last word ended in.



(Edit: Each word cannot be used more than once. Other than that there are no other constraints.)



I want the output to give the longest word chain sequence, which in this case is:



['hedgehog', 'giraffe', 'elephant', 'tiger', 'racoon']


I'm not really sure how to do it, I had different attempts at trying this. One of them...



This code finds the word chain correctly if we start with a specific word from the list, e.g. words[0] (so 'giraffe'):



words = ['giraffe', 'elephant', 'ant', 'tiger', 'racoon', 'cat', 'hedgehog', 'mouse']

word_chain =

word_chain.append(words[0])

for word in words:
for char in word[0]:

if char == word_chain[-1][-1]:
word_chain.append(word)

print(word_chain)


Output:



['giraffe', 'elephant', 'tiger', 'racoon']


BUT, I want to find the longest possible chain of words (explained above).



My method: So, I tried to use the above working code that I wrote and loop through, using each word from the list as the starting point and finding the word chain for each word[0], word[1], word[2] etc. Then I tried to find the longest word chain by using an if statement and compare the length to the previous longest chain, but I can't get it done properly and I don't really know where this is going.



words = ['giraffe', 'elephant', 'ant', 'tiger', 'racoon', 'cat', 'hedgehog', 'mouse']

word_chain =
max_length = 0
for starting_word_index in range(len(words) - 1):

word_chain.append(words[starting_word_index])

for word in words:
for char in word[0]:

if char == word_chain[-1][-1]:
word_chain.append(word)

# Not sure

if len(word_chain) > max_length:
final_word_chain = word_chain
longest = len(word_chain)
word_chain.clear()

print(final_word_chain)


This is my nth attempt, I think this one prints an empty list, I had different attempts before this that failed to clear the word_chain list properly and ended up repeating words over again.



Any help much appreciated. Hopefully I didn't make this too teedious or confusing... Thanks!










share|improve this question









New contributor




Mandingo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.




















  • @dataLeo Hi, each word cannot be used more than once (so elephant can only be used once), no other constraints apart from that. Aim is to find the longest word chain sequence.
    – Mandingo
    11 hours ago












  • Do you need an added precaution in case someone slips in a name that start and ends with the same letter? (… not as if I can come up with one ...)
    – usr2564301
    10 hours ago










  • This would be a great contribution to codegolf.stackexchange.com
    – Frozenthia
    9 hours ago












  • This sounds like a problem for some graph theory. I'll take a look at it when I get home.
    – Mateen Ulhaq
    1 hour ago















up vote
16
down vote

favorite
5









up vote
16
down vote

favorite
5






5





So, this is a part of a function I'm trying to make.



I don't want the code to be too complicated.



I have a list of words, e.g.



words = ['giraffe', 'elephant', 'ant', 'tiger', 'racoon', 'cat', 'hedgehog', 'mouse']


The idea of the word chain sequence is for the next word to begin with the letter that the last word ended in.



(Edit: Each word cannot be used more than once. Other than that there are no other constraints.)



I want the output to give the longest word chain sequence, which in this case is:



['hedgehog', 'giraffe', 'elephant', 'tiger', 'racoon']


I'm not really sure how to do it, I had different attempts at trying this. One of them...



This code finds the word chain correctly if we start with a specific word from the list, e.g. words[0] (so 'giraffe'):



words = ['giraffe', 'elephant', 'ant', 'tiger', 'racoon', 'cat', 'hedgehog', 'mouse']

word_chain =

word_chain.append(words[0])

for word in words:
for char in word[0]:

if char == word_chain[-1][-1]:
word_chain.append(word)

print(word_chain)


Output:



['giraffe', 'elephant', 'tiger', 'racoon']


BUT, I want to find the longest possible chain of words (explained above).



My method: So, I tried to use the above working code that I wrote and loop through, using each word from the list as the starting point and finding the word chain for each word[0], word[1], word[2] etc. Then I tried to find the longest word chain by using an if statement and compare the length to the previous longest chain, but I can't get it done properly and I don't really know where this is going.



words = ['giraffe', 'elephant', 'ant', 'tiger', 'racoon', 'cat', 'hedgehog', 'mouse']

word_chain =
max_length = 0
for starting_word_index in range(len(words) - 1):

word_chain.append(words[starting_word_index])

for word in words:
for char in word[0]:

if char == word_chain[-1][-1]:
word_chain.append(word)

# Not sure

if len(word_chain) > max_length:
final_word_chain = word_chain
longest = len(word_chain)
word_chain.clear()

print(final_word_chain)


This is my nth attempt, I think this one prints an empty list, I had different attempts before this that failed to clear the word_chain list properly and ended up repeating words over again.



Any help much appreciated. Hopefully I didn't make this too teedious or confusing... Thanks!










share|improve this question









New contributor




Mandingo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











So, this is a part of a function I'm trying to make.



I don't want the code to be too complicated.



I have a list of words, e.g.



words = ['giraffe', 'elephant', 'ant', 'tiger', 'racoon', 'cat', 'hedgehog', 'mouse']


The idea of the word chain sequence is for the next word to begin with the letter that the last word ended in.



(Edit: Each word cannot be used more than once. Other than that there are no other constraints.)



I want the output to give the longest word chain sequence, which in this case is:



['hedgehog', 'giraffe', 'elephant', 'tiger', 'racoon']


I'm not really sure how to do it, I had different attempts at trying this. One of them...



This code finds the word chain correctly if we start with a specific word from the list, e.g. words[0] (so 'giraffe'):



words = ['giraffe', 'elephant', 'ant', 'tiger', 'racoon', 'cat', 'hedgehog', 'mouse']

word_chain =

word_chain.append(words[0])

for word in words:
for char in word[0]:

if char == word_chain[-1][-1]:
word_chain.append(word)

print(word_chain)


Output:



['giraffe', 'elephant', 'tiger', 'racoon']


BUT, I want to find the longest possible chain of words (explained above).



My method: So, I tried to use the above working code that I wrote and loop through, using each word from the list as the starting point and finding the word chain for each word[0], word[1], word[2] etc. Then I tried to find the longest word chain by using an if statement and compare the length to the previous longest chain, but I can't get it done properly and I don't really know where this is going.



words = ['giraffe', 'elephant', 'ant', 'tiger', 'racoon', 'cat', 'hedgehog', 'mouse']

word_chain =
max_length = 0
for starting_word_index in range(len(words) - 1):

word_chain.append(words[starting_word_index])

for word in words:
for char in word[0]:

if char == word_chain[-1][-1]:
word_chain.append(word)

# Not sure

if len(word_chain) > max_length:
final_word_chain = word_chain
longest = len(word_chain)
word_chain.clear()

print(final_word_chain)


This is my nth attempt, I think this one prints an empty list, I had different attempts before this that failed to clear the word_chain list properly and ended up repeating words over again.



Any help much appreciated. Hopefully I didn't make this too teedious or confusing... Thanks!







python






share|improve this question









New contributor




Mandingo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




Mandingo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited 11 hours ago





















New contributor




Mandingo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 11 hours ago









Mandingo

1328




1328




New contributor




Mandingo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





Mandingo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






Mandingo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.












  • @dataLeo Hi, each word cannot be used more than once (so elephant can only be used once), no other constraints apart from that. Aim is to find the longest word chain sequence.
    – Mandingo
    11 hours ago












  • Do you need an added precaution in case someone slips in a name that start and ends with the same letter? (… not as if I can come up with one ...)
    – usr2564301
    10 hours ago










  • This would be a great contribution to codegolf.stackexchange.com
    – Frozenthia
    9 hours ago












  • This sounds like a problem for some graph theory. I'll take a look at it when I get home.
    – Mateen Ulhaq
    1 hour ago




















  • @dataLeo Hi, each word cannot be used more than once (so elephant can only be used once), no other constraints apart from that. Aim is to find the longest word chain sequence.
    – Mandingo
    11 hours ago












  • Do you need an added precaution in case someone slips in a name that start and ends with the same letter? (… not as if I can come up with one ...)
    – usr2564301
    10 hours ago










  • This would be a great contribution to codegolf.stackexchange.com
    – Frozenthia
    9 hours ago












  • This sounds like a problem for some graph theory. I'll take a look at it when I get home.
    – Mateen Ulhaq
    1 hour ago


















@dataLeo Hi, each word cannot be used more than once (so elephant can only be used once), no other constraints apart from that. Aim is to find the longest word chain sequence.
– Mandingo
11 hours ago






@dataLeo Hi, each word cannot be used more than once (so elephant can only be used once), no other constraints apart from that. Aim is to find the longest word chain sequence.
– Mandingo
11 hours ago














Do you need an added precaution in case someone slips in a name that start and ends with the same letter? (… not as if I can come up with one ...)
– usr2564301
10 hours ago




Do you need an added precaution in case someone slips in a name that start and ends with the same letter? (… not as if I can come up with one ...)
– usr2564301
10 hours ago












This would be a great contribution to codegolf.stackexchange.com
– Frozenthia
9 hours ago






This would be a great contribution to codegolf.stackexchange.com
– Frozenthia
9 hours ago














This sounds like a problem for some graph theory. I'll take a look at it when I get home.
– Mateen Ulhaq
1 hour ago






This sounds like a problem for some graph theory. I'll take a look at it when I get home.
– Mateen Ulhaq
1 hour ago














7 Answers
7






active

oldest

votes

















up vote
8
down vote













You can use recursion to explore every "branch" that emerges when every possible letter containing the proper initial character is added to a running list:



words = ['giraffe', 'elephant', 'ant', 'tiger', 'racoon', 'cat', 'hedgehog', 'mouse']
def get_results(_start, _current, _seen):
if all(c in _seen for c in words if c[0] == _start[-1]):
yield _current
else:
for i in words:
if i[0] == _start[-1]:
yield from get_results(i, _current+[i], _seen+[i])


new_d = [list(get_results(i, [i], ))[0] for i in words]
final_d = max([i for i in new_d if len(i) == len(set(i))], key=len)


Output:



['hedgehog', 'giraffe', 'elephant', 'tiger', 'racoon']


This solution works similar to the breadth-first search, as the function get_resuls will continue to iterate over the entire list as long as the current value has not been called on before. Values that have been seen by the function are added to the _seen list, ultimately ceasing the stream of recursive calls.



This solution will also ignore results with duplicates:



words = ['giraffe', 'elephant', 'ant', 'ning', 'tiger', 'racoon', 'cat', 'hedgehog', 'mouse',]
new_d = [list(get_results(i, [i], ))[0] for i in words]
final_d = max([i for i in new_d if len(i) == len(set(i))], key=len)


Output:



['ant', 'tiger', 'racoon', 'ning', 'giraffe', 'elephant']





share|improve this answer






























    up vote
    2
    down vote













    Here is a working recursive brute-force approach:



    def brute_force(pool, last=None, so_far=None):
    so_far = so_far or
    if not pool:
    return so_far
    candidates =
    for w in pool:
    if not last or w.startswith(last):
    c_so_far, c_pool = list(so_far) + [w], set(pool) - set([w])
    candidates.append(brute_force(c_pool, w[-1], c_so_far))
    return max(candidates, key=len, default=so_far)

    >>> brute_force(words)
    ['hedgehog', 'giraffe', 'elephant', 'tiger', 'racoon']


    At every recursive call, this tries to continue the chain with every eligible word form the remaining pool. It then chooses the longest such continuation.






    share|improve this answer






























      up vote
      2
      down vote













      This function creates an iterator (see: What does the "yield" keyword do?) which recursively calls the same iterator to create all possible tail sequences:



      words = ['giraffe', 'elephant', 'ant', 'tiger', 'racoon', 'cat', 'hedgehog', 'mouse']

      def chains(words, previous_word=None):
      # Consider an empty sequence to be valid (as a "tail" or on its own):
      yield
      # Remove the previous word, if any, from consideration, both here and in any subcalls:
      words = [word for word in words if word != previous_word]
      # Take each remaining word...
      for each_word in words:
      # ...provided it obeys the chaining rule
      if not previous_word or each_word.startswith(previous_word[-1]):
      # and recurse to consider all possible tail sequences that can follow this particular word:
      for tail in chains(words, previous_word=each_word):
      # Concatenate the word we're considering with each possible tail:
      yield [each_word] + tail

      all_legal_sequences = list(chains(words)) # convert the output (an iterator) to a list
      all_legal_sequences.sort(key=len) # sort the list of chains in increasing order of chain length
      print(all_legal_sequences[-1]) # print the last (and therefore longest) chain
      # Prints: ['hedgehog', 'giraffe', 'elephant', 'tiger', 'racoon']





      share|improve this answer






























        up vote
        2
        down vote













        In the spirit of brute force solutions, you can check all permutations of the words list and choose the best continuous starting sequence:



        from itertools import permutations

        def continuous_starting_sequence(words):
        chain = [words[0]]
        for i in range(1, len(words)):
        if not words[i].startswith(words[i - 1][-1]):
        break
        chain.append(words[i])
        return chain

        words = ['giraffe', 'elephant', 'ant', 'tiger', 'racoon', 'cat', 'hedgehog', 'mouse']
        best = max((continuous_starting_sequence(seq) for seq in permutations(words)), key=len)

        print(best)
        # ['hedgehog', 'giraffe', 'elephant', 'tiger', 'racoon']


        Since we're considering all permutations, we know that there must be a permutation that starts with the largest word chain.



        This, of course, has O(n n!) time complexity :D






        share|improve this answer






























          up vote
          1
          down vote













          Another answer using a recursive approach:



          def word_list(w_list, remaining_list):
          max_result_len=0
          res = w_list
          for word_index in range(len(remaining_list)):
          # if the last letter of the word list is equal to the first letter of the word
          if w_list[-1][-1] == remaining_list[word_index][0]:
          # make copies of the lists to not alter it in the caller function
          w_list_copy = w_list.copy()
          remaining_list_copy = remaining_list.copy()
          # removes the used word from the remaining list
          remaining_list_copy.pop(word_index)
          # append the matching word to the new word list
          w_list_copy.append(remaining_list[word_index])
          res_aux = word_list(w_list_copy, remaining_list_copy)
          # Keep only the longest list
          res = res_aux if len(res_aux) > max_result_len else res
          return res

          words = ['giraffe', 'elephant', 'ant', 'tiger', 'racoon', 'cat', 'hedgehog', 'mouse']
          word_list(['dog'], words)


          output:



          ['dog', 'giraffe', 'elephant', 'tiger', 'racoon']





          share|improve this answer




























            up vote
            1
            down vote













            Hopefully, a more intuitive way of doing it without recursion. Iterate through the list and let Python's sort and list comprehension do the work for you:



            words = ['giraffe', 'elephant', 'ant', 'tiger', 'racoon', 'cat', 'hedgehog', 'mouse']

            def chain_longest(pivot, words):
            new_words =
            new_words.append(pivot)
            for word in words:
            potential_words = [i for i in words if i.startswith(pivot[-1]) and i not in new_words]
            if potential_words:
            next_word = sorted(potential_words, key = lambda x: len)[0]
            new_words.append(next_word)
            pivot = next_word
            else:
            pass
            return new_words

            max([chain_longest(i, words) for i in words], key = len)
            >>
            ['hedgehog', 'giraffe', 'elephant', 'tiger', 'racoon']


            Set a pivot and check for potential_words if they start with your pivot word and do not appear in your new list of words. If found then just sort them by length and take the first element.



            The list comprehension goes through every word as a pivot and returns you the longest chain.






            share|improve this answer























            • The expected output and longest word chain is: ['hedgehog', 'giraffe', 'elephant', 'tiger', 'racoon'], your one gives ['giraffe', 'elephant', 'tiger', 'racoon'] or am I missing something?
              – Mandingo
              10 hours ago






            • 1




              You can replace key = lambda x: len(x) with key=len.
              – Keyur Potdar
              10 hours ago






            • 1




              @mandingo sorry I got confused with the output. Let me change that.
              – BernardL
              10 hours ago


















            up vote
            1
            down vote













            I have a tree-based approach for this question which might be faster. I am still working on implementation of the code but here is what I would do:



                1. Form a tree with the root node as first word. 
            2. Form the branches if there is any word or words that starts
            with the alphabet with which this current word ends.
            3. Exhaust the entire given list based on the ending alphabet
            of current word and form the entire tree.
            4. Now just find the longest path of this tree and store it.
            5. Repeat steps 1 to 4 for each of the words given in the list
            and print the longest path among the longest paths we got above.


            I hope this might give a better solution in case there is a large list of words given. I will update this with the actual code implementation.






            share|improve this answer





















              Your Answer






              StackExchange.ifUsing("editor", function () {
              StackExchange.using("externalEditor", function () {
              StackExchange.using("snippets", function () {
              StackExchange.snippets.init();
              });
              });
              }, "code-snippets");

              StackExchange.ready(function() {
              var channelOptions = {
              tags: "".split(" "),
              id: "1"
              };
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function() {
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled) {
              StackExchange.using("snippets", function() {
              createEditor();
              });
              }
              else {
              createEditor();
              }
              });

              function createEditor() {
              StackExchange.prepareEditor({
              heartbeatType: 'answer',
              convertImagesToLinks: true,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              imageUploader: {
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              },
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              });


              }
              });






              Mandingo is a new contributor. Be nice, and check out our Code of Conduct.










               

              draft saved


              draft discarded


















              StackExchange.ready(
              function () {
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53485052%2flongest-word-chain-from-a-list-of-words%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              7 Answers
              7






              active

              oldest

              votes








              7 Answers
              7






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes








              up vote
              8
              down vote













              You can use recursion to explore every "branch" that emerges when every possible letter containing the proper initial character is added to a running list:



              words = ['giraffe', 'elephant', 'ant', 'tiger', 'racoon', 'cat', 'hedgehog', 'mouse']
              def get_results(_start, _current, _seen):
              if all(c in _seen for c in words if c[0] == _start[-1]):
              yield _current
              else:
              for i in words:
              if i[0] == _start[-1]:
              yield from get_results(i, _current+[i], _seen+[i])


              new_d = [list(get_results(i, [i], ))[0] for i in words]
              final_d = max([i for i in new_d if len(i) == len(set(i))], key=len)


              Output:



              ['hedgehog', 'giraffe', 'elephant', 'tiger', 'racoon']


              This solution works similar to the breadth-first search, as the function get_resuls will continue to iterate over the entire list as long as the current value has not been called on before. Values that have been seen by the function are added to the _seen list, ultimately ceasing the stream of recursive calls.



              This solution will also ignore results with duplicates:



              words = ['giraffe', 'elephant', 'ant', 'ning', 'tiger', 'racoon', 'cat', 'hedgehog', 'mouse',]
              new_d = [list(get_results(i, [i], ))[0] for i in words]
              final_d = max([i for i in new_d if len(i) == len(set(i))], key=len)


              Output:



              ['ant', 'tiger', 'racoon', 'ning', 'giraffe', 'elephant']





              share|improve this answer



























                up vote
                8
                down vote













                You can use recursion to explore every "branch" that emerges when every possible letter containing the proper initial character is added to a running list:



                words = ['giraffe', 'elephant', 'ant', 'tiger', 'racoon', 'cat', 'hedgehog', 'mouse']
                def get_results(_start, _current, _seen):
                if all(c in _seen for c in words if c[0] == _start[-1]):
                yield _current
                else:
                for i in words:
                if i[0] == _start[-1]:
                yield from get_results(i, _current+[i], _seen+[i])


                new_d = [list(get_results(i, [i], ))[0] for i in words]
                final_d = max([i for i in new_d if len(i) == len(set(i))], key=len)


                Output:



                ['hedgehog', 'giraffe', 'elephant', 'tiger', 'racoon']


                This solution works similar to the breadth-first search, as the function get_resuls will continue to iterate over the entire list as long as the current value has not been called on before. Values that have been seen by the function are added to the _seen list, ultimately ceasing the stream of recursive calls.



                This solution will also ignore results with duplicates:



                words = ['giraffe', 'elephant', 'ant', 'ning', 'tiger', 'racoon', 'cat', 'hedgehog', 'mouse',]
                new_d = [list(get_results(i, [i], ))[0] for i in words]
                final_d = max([i for i in new_d if len(i) == len(set(i))], key=len)


                Output:



                ['ant', 'tiger', 'racoon', 'ning', 'giraffe', 'elephant']





                share|improve this answer

























                  up vote
                  8
                  down vote










                  up vote
                  8
                  down vote









                  You can use recursion to explore every "branch" that emerges when every possible letter containing the proper initial character is added to a running list:



                  words = ['giraffe', 'elephant', 'ant', 'tiger', 'racoon', 'cat', 'hedgehog', 'mouse']
                  def get_results(_start, _current, _seen):
                  if all(c in _seen for c in words if c[0] == _start[-1]):
                  yield _current
                  else:
                  for i in words:
                  if i[0] == _start[-1]:
                  yield from get_results(i, _current+[i], _seen+[i])


                  new_d = [list(get_results(i, [i], ))[0] for i in words]
                  final_d = max([i for i in new_d if len(i) == len(set(i))], key=len)


                  Output:



                  ['hedgehog', 'giraffe', 'elephant', 'tiger', 'racoon']


                  This solution works similar to the breadth-first search, as the function get_resuls will continue to iterate over the entire list as long as the current value has not been called on before. Values that have been seen by the function are added to the _seen list, ultimately ceasing the stream of recursive calls.



                  This solution will also ignore results with duplicates:



                  words = ['giraffe', 'elephant', 'ant', 'ning', 'tiger', 'racoon', 'cat', 'hedgehog', 'mouse',]
                  new_d = [list(get_results(i, [i], ))[0] for i in words]
                  final_d = max([i for i in new_d if len(i) == len(set(i))], key=len)


                  Output:



                  ['ant', 'tiger', 'racoon', 'ning', 'giraffe', 'elephant']





                  share|improve this answer














                  You can use recursion to explore every "branch" that emerges when every possible letter containing the proper initial character is added to a running list:



                  words = ['giraffe', 'elephant', 'ant', 'tiger', 'racoon', 'cat', 'hedgehog', 'mouse']
                  def get_results(_start, _current, _seen):
                  if all(c in _seen for c in words if c[0] == _start[-1]):
                  yield _current
                  else:
                  for i in words:
                  if i[0] == _start[-1]:
                  yield from get_results(i, _current+[i], _seen+[i])


                  new_d = [list(get_results(i, [i], ))[0] for i in words]
                  final_d = max([i for i in new_d if len(i) == len(set(i))], key=len)


                  Output:



                  ['hedgehog', 'giraffe', 'elephant', 'tiger', 'racoon']


                  This solution works similar to the breadth-first search, as the function get_resuls will continue to iterate over the entire list as long as the current value has not been called on before. Values that have been seen by the function are added to the _seen list, ultimately ceasing the stream of recursive calls.



                  This solution will also ignore results with duplicates:



                  words = ['giraffe', 'elephant', 'ant', 'ning', 'tiger', 'racoon', 'cat', 'hedgehog', 'mouse',]
                  new_d = [list(get_results(i, [i], ))[0] for i in words]
                  final_d = max([i for i in new_d if len(i) == len(set(i))], key=len)


                  Output:



                  ['ant', 'tiger', 'racoon', 'ning', 'giraffe', 'elephant']






                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited 40 mins ago

























                  answered 10 hours ago









                  Ajax1234

                  38.7k42351




                  38.7k42351
























                      up vote
                      2
                      down vote













                      Here is a working recursive brute-force approach:



                      def brute_force(pool, last=None, so_far=None):
                      so_far = so_far or
                      if not pool:
                      return so_far
                      candidates =
                      for w in pool:
                      if not last or w.startswith(last):
                      c_so_far, c_pool = list(so_far) + [w], set(pool) - set([w])
                      candidates.append(brute_force(c_pool, w[-1], c_so_far))
                      return max(candidates, key=len, default=so_far)

                      >>> brute_force(words)
                      ['hedgehog', 'giraffe', 'elephant', 'tiger', 'racoon']


                      At every recursive call, this tries to continue the chain with every eligible word form the remaining pool. It then chooses the longest such continuation.






                      share|improve this answer



























                        up vote
                        2
                        down vote













                        Here is a working recursive brute-force approach:



                        def brute_force(pool, last=None, so_far=None):
                        so_far = so_far or
                        if not pool:
                        return so_far
                        candidates =
                        for w in pool:
                        if not last or w.startswith(last):
                        c_so_far, c_pool = list(so_far) + [w], set(pool) - set([w])
                        candidates.append(brute_force(c_pool, w[-1], c_so_far))
                        return max(candidates, key=len, default=so_far)

                        >>> brute_force(words)
                        ['hedgehog', 'giraffe', 'elephant', 'tiger', 'racoon']


                        At every recursive call, this tries to continue the chain with every eligible word form the remaining pool. It then chooses the longest such continuation.






                        share|improve this answer

























                          up vote
                          2
                          down vote










                          up vote
                          2
                          down vote









                          Here is a working recursive brute-force approach:



                          def brute_force(pool, last=None, so_far=None):
                          so_far = so_far or
                          if not pool:
                          return so_far
                          candidates =
                          for w in pool:
                          if not last or w.startswith(last):
                          c_so_far, c_pool = list(so_far) + [w], set(pool) - set([w])
                          candidates.append(brute_force(c_pool, w[-1], c_so_far))
                          return max(candidates, key=len, default=so_far)

                          >>> brute_force(words)
                          ['hedgehog', 'giraffe', 'elephant', 'tiger', 'racoon']


                          At every recursive call, this tries to continue the chain with every eligible word form the remaining pool. It then chooses the longest such continuation.






                          share|improve this answer














                          Here is a working recursive brute-force approach:



                          def brute_force(pool, last=None, so_far=None):
                          so_far = so_far or
                          if not pool:
                          return so_far
                          candidates =
                          for w in pool:
                          if not last or w.startswith(last):
                          c_so_far, c_pool = list(so_far) + [w], set(pool) - set([w])
                          candidates.append(brute_force(c_pool, w[-1], c_so_far))
                          return max(candidates, key=len, default=so_far)

                          >>> brute_force(words)
                          ['hedgehog', 'giraffe', 'elephant', 'tiger', 'racoon']


                          At every recursive call, this tries to continue the chain with every eligible word form the remaining pool. It then chooses the longest such continuation.







                          share|improve this answer














                          share|improve this answer



                          share|improve this answer








                          edited 10 hours ago

























                          answered 10 hours ago









                          schwobaseggl

                          35k31937




                          35k31937






















                              up vote
                              2
                              down vote













                              This function creates an iterator (see: What does the "yield" keyword do?) which recursively calls the same iterator to create all possible tail sequences:



                              words = ['giraffe', 'elephant', 'ant', 'tiger', 'racoon', 'cat', 'hedgehog', 'mouse']

                              def chains(words, previous_word=None):
                              # Consider an empty sequence to be valid (as a "tail" or on its own):
                              yield
                              # Remove the previous word, if any, from consideration, both here and in any subcalls:
                              words = [word for word in words if word != previous_word]
                              # Take each remaining word...
                              for each_word in words:
                              # ...provided it obeys the chaining rule
                              if not previous_word or each_word.startswith(previous_word[-1]):
                              # and recurse to consider all possible tail sequences that can follow this particular word:
                              for tail in chains(words, previous_word=each_word):
                              # Concatenate the word we're considering with each possible tail:
                              yield [each_word] + tail

                              all_legal_sequences = list(chains(words)) # convert the output (an iterator) to a list
                              all_legal_sequences.sort(key=len) # sort the list of chains in increasing order of chain length
                              print(all_legal_sequences[-1]) # print the last (and therefore longest) chain
                              # Prints: ['hedgehog', 'giraffe', 'elephant', 'tiger', 'racoon']





                              share|improve this answer



























                                up vote
                                2
                                down vote













                                This function creates an iterator (see: What does the "yield" keyword do?) which recursively calls the same iterator to create all possible tail sequences:



                                words = ['giraffe', 'elephant', 'ant', 'tiger', 'racoon', 'cat', 'hedgehog', 'mouse']

                                def chains(words, previous_word=None):
                                # Consider an empty sequence to be valid (as a "tail" or on its own):
                                yield
                                # Remove the previous word, if any, from consideration, both here and in any subcalls:
                                words = [word for word in words if word != previous_word]
                                # Take each remaining word...
                                for each_word in words:
                                # ...provided it obeys the chaining rule
                                if not previous_word or each_word.startswith(previous_word[-1]):
                                # and recurse to consider all possible tail sequences that can follow this particular word:
                                for tail in chains(words, previous_word=each_word):
                                # Concatenate the word we're considering with each possible tail:
                                yield [each_word] + tail

                                all_legal_sequences = list(chains(words)) # convert the output (an iterator) to a list
                                all_legal_sequences.sort(key=len) # sort the list of chains in increasing order of chain length
                                print(all_legal_sequences[-1]) # print the last (and therefore longest) chain
                                # Prints: ['hedgehog', 'giraffe', 'elephant', 'tiger', 'racoon']





                                share|improve this answer

























                                  up vote
                                  2
                                  down vote










                                  up vote
                                  2
                                  down vote









                                  This function creates an iterator (see: What does the "yield" keyword do?) which recursively calls the same iterator to create all possible tail sequences:



                                  words = ['giraffe', 'elephant', 'ant', 'tiger', 'racoon', 'cat', 'hedgehog', 'mouse']

                                  def chains(words, previous_word=None):
                                  # Consider an empty sequence to be valid (as a "tail" or on its own):
                                  yield
                                  # Remove the previous word, if any, from consideration, both here and in any subcalls:
                                  words = [word for word in words if word != previous_word]
                                  # Take each remaining word...
                                  for each_word in words:
                                  # ...provided it obeys the chaining rule
                                  if not previous_word or each_word.startswith(previous_word[-1]):
                                  # and recurse to consider all possible tail sequences that can follow this particular word:
                                  for tail in chains(words, previous_word=each_word):
                                  # Concatenate the word we're considering with each possible tail:
                                  yield [each_word] + tail

                                  all_legal_sequences = list(chains(words)) # convert the output (an iterator) to a list
                                  all_legal_sequences.sort(key=len) # sort the list of chains in increasing order of chain length
                                  print(all_legal_sequences[-1]) # print the last (and therefore longest) chain
                                  # Prints: ['hedgehog', 'giraffe', 'elephant', 'tiger', 'racoon']





                                  share|improve this answer














                                  This function creates an iterator (see: What does the "yield" keyword do?) which recursively calls the same iterator to create all possible tail sequences:



                                  words = ['giraffe', 'elephant', 'ant', 'tiger', 'racoon', 'cat', 'hedgehog', 'mouse']

                                  def chains(words, previous_word=None):
                                  # Consider an empty sequence to be valid (as a "tail" or on its own):
                                  yield
                                  # Remove the previous word, if any, from consideration, both here and in any subcalls:
                                  words = [word for word in words if word != previous_word]
                                  # Take each remaining word...
                                  for each_word in words:
                                  # ...provided it obeys the chaining rule
                                  if not previous_word or each_word.startswith(previous_word[-1]):
                                  # and recurse to consider all possible tail sequences that can follow this particular word:
                                  for tail in chains(words, previous_word=each_word):
                                  # Concatenate the word we're considering with each possible tail:
                                  yield [each_word] + tail

                                  all_legal_sequences = list(chains(words)) # convert the output (an iterator) to a list
                                  all_legal_sequences.sort(key=len) # sort the list of chains in increasing order of chain length
                                  print(all_legal_sequences[-1]) # print the last (and therefore longest) chain
                                  # Prints: ['hedgehog', 'giraffe', 'elephant', 'tiger', 'racoon']






                                  share|improve this answer














                                  share|improve this answer



                                  share|improve this answer








                                  edited 10 hours ago

























                                  answered 10 hours ago









                                  jez

                                  7,4651739




                                  7,4651739






















                                      up vote
                                      2
                                      down vote













                                      In the spirit of brute force solutions, you can check all permutations of the words list and choose the best continuous starting sequence:



                                      from itertools import permutations

                                      def continuous_starting_sequence(words):
                                      chain = [words[0]]
                                      for i in range(1, len(words)):
                                      if not words[i].startswith(words[i - 1][-1]):
                                      break
                                      chain.append(words[i])
                                      return chain

                                      words = ['giraffe', 'elephant', 'ant', 'tiger', 'racoon', 'cat', 'hedgehog', 'mouse']
                                      best = max((continuous_starting_sequence(seq) for seq in permutations(words)), key=len)

                                      print(best)
                                      # ['hedgehog', 'giraffe', 'elephant', 'tiger', 'racoon']


                                      Since we're considering all permutations, we know that there must be a permutation that starts with the largest word chain.



                                      This, of course, has O(n n!) time complexity :D






                                      share|improve this answer



























                                        up vote
                                        2
                                        down vote













                                        In the spirit of brute force solutions, you can check all permutations of the words list and choose the best continuous starting sequence:



                                        from itertools import permutations

                                        def continuous_starting_sequence(words):
                                        chain = [words[0]]
                                        for i in range(1, len(words)):
                                        if not words[i].startswith(words[i - 1][-1]):
                                        break
                                        chain.append(words[i])
                                        return chain

                                        words = ['giraffe', 'elephant', 'ant', 'tiger', 'racoon', 'cat', 'hedgehog', 'mouse']
                                        best = max((continuous_starting_sequence(seq) for seq in permutations(words)), key=len)

                                        print(best)
                                        # ['hedgehog', 'giraffe', 'elephant', 'tiger', 'racoon']


                                        Since we're considering all permutations, we know that there must be a permutation that starts with the largest word chain.



                                        This, of course, has O(n n!) time complexity :D






                                        share|improve this answer

























                                          up vote
                                          2
                                          down vote










                                          up vote
                                          2
                                          down vote









                                          In the spirit of brute force solutions, you can check all permutations of the words list and choose the best continuous starting sequence:



                                          from itertools import permutations

                                          def continuous_starting_sequence(words):
                                          chain = [words[0]]
                                          for i in range(1, len(words)):
                                          if not words[i].startswith(words[i - 1][-1]):
                                          break
                                          chain.append(words[i])
                                          return chain

                                          words = ['giraffe', 'elephant', 'ant', 'tiger', 'racoon', 'cat', 'hedgehog', 'mouse']
                                          best = max((continuous_starting_sequence(seq) for seq in permutations(words)), key=len)

                                          print(best)
                                          # ['hedgehog', 'giraffe', 'elephant', 'tiger', 'racoon']


                                          Since we're considering all permutations, we know that there must be a permutation that starts with the largest word chain.



                                          This, of course, has O(n n!) time complexity :D






                                          share|improve this answer














                                          In the spirit of brute force solutions, you can check all permutations of the words list and choose the best continuous starting sequence:



                                          from itertools import permutations

                                          def continuous_starting_sequence(words):
                                          chain = [words[0]]
                                          for i in range(1, len(words)):
                                          if not words[i].startswith(words[i - 1][-1]):
                                          break
                                          chain.append(words[i])
                                          return chain

                                          words = ['giraffe', 'elephant', 'ant', 'tiger', 'racoon', 'cat', 'hedgehog', 'mouse']
                                          best = max((continuous_starting_sequence(seq) for seq in permutations(words)), key=len)

                                          print(best)
                                          # ['hedgehog', 'giraffe', 'elephant', 'tiger', 'racoon']


                                          Since we're considering all permutations, we know that there must be a permutation that starts with the largest word chain.



                                          This, of course, has O(n n!) time complexity :D







                                          share|improve this answer














                                          share|improve this answer



                                          share|improve this answer








                                          edited 7 hours ago

























                                          answered 9 hours ago









                                          slider

                                          6,8491129




                                          6,8491129






















                                              up vote
                                              1
                                              down vote













                                              Another answer using a recursive approach:



                                              def word_list(w_list, remaining_list):
                                              max_result_len=0
                                              res = w_list
                                              for word_index in range(len(remaining_list)):
                                              # if the last letter of the word list is equal to the first letter of the word
                                              if w_list[-1][-1] == remaining_list[word_index][0]:
                                              # make copies of the lists to not alter it in the caller function
                                              w_list_copy = w_list.copy()
                                              remaining_list_copy = remaining_list.copy()
                                              # removes the used word from the remaining list
                                              remaining_list_copy.pop(word_index)
                                              # append the matching word to the new word list
                                              w_list_copy.append(remaining_list[word_index])
                                              res_aux = word_list(w_list_copy, remaining_list_copy)
                                              # Keep only the longest list
                                              res = res_aux if len(res_aux) > max_result_len else res
                                              return res

                                              words = ['giraffe', 'elephant', 'ant', 'tiger', 'racoon', 'cat', 'hedgehog', 'mouse']
                                              word_list(['dog'], words)


                                              output:



                                              ['dog', 'giraffe', 'elephant', 'tiger', 'racoon']





                                              share|improve this answer

























                                                up vote
                                                1
                                                down vote













                                                Another answer using a recursive approach:



                                                def word_list(w_list, remaining_list):
                                                max_result_len=0
                                                res = w_list
                                                for word_index in range(len(remaining_list)):
                                                # if the last letter of the word list is equal to the first letter of the word
                                                if w_list[-1][-1] == remaining_list[word_index][0]:
                                                # make copies of the lists to not alter it in the caller function
                                                w_list_copy = w_list.copy()
                                                remaining_list_copy = remaining_list.copy()
                                                # removes the used word from the remaining list
                                                remaining_list_copy.pop(word_index)
                                                # append the matching word to the new word list
                                                w_list_copy.append(remaining_list[word_index])
                                                res_aux = word_list(w_list_copy, remaining_list_copy)
                                                # Keep only the longest list
                                                res = res_aux if len(res_aux) > max_result_len else res
                                                return res

                                                words = ['giraffe', 'elephant', 'ant', 'tiger', 'racoon', 'cat', 'hedgehog', 'mouse']
                                                word_list(['dog'], words)


                                                output:



                                                ['dog', 'giraffe', 'elephant', 'tiger', 'racoon']





                                                share|improve this answer























                                                  up vote
                                                  1
                                                  down vote










                                                  up vote
                                                  1
                                                  down vote









                                                  Another answer using a recursive approach:



                                                  def word_list(w_list, remaining_list):
                                                  max_result_len=0
                                                  res = w_list
                                                  for word_index in range(len(remaining_list)):
                                                  # if the last letter of the word list is equal to the first letter of the word
                                                  if w_list[-1][-1] == remaining_list[word_index][0]:
                                                  # make copies of the lists to not alter it in the caller function
                                                  w_list_copy = w_list.copy()
                                                  remaining_list_copy = remaining_list.copy()
                                                  # removes the used word from the remaining list
                                                  remaining_list_copy.pop(word_index)
                                                  # append the matching word to the new word list
                                                  w_list_copy.append(remaining_list[word_index])
                                                  res_aux = word_list(w_list_copy, remaining_list_copy)
                                                  # Keep only the longest list
                                                  res = res_aux if len(res_aux) > max_result_len else res
                                                  return res

                                                  words = ['giraffe', 'elephant', 'ant', 'tiger', 'racoon', 'cat', 'hedgehog', 'mouse']
                                                  word_list(['dog'], words)


                                                  output:



                                                  ['dog', 'giraffe', 'elephant', 'tiger', 'racoon']





                                                  share|improve this answer












                                                  Another answer using a recursive approach:



                                                  def word_list(w_list, remaining_list):
                                                  max_result_len=0
                                                  res = w_list
                                                  for word_index in range(len(remaining_list)):
                                                  # if the last letter of the word list is equal to the first letter of the word
                                                  if w_list[-1][-1] == remaining_list[word_index][0]:
                                                  # make copies of the lists to not alter it in the caller function
                                                  w_list_copy = w_list.copy()
                                                  remaining_list_copy = remaining_list.copy()
                                                  # removes the used word from the remaining list
                                                  remaining_list_copy.pop(word_index)
                                                  # append the matching word to the new word list
                                                  w_list_copy.append(remaining_list[word_index])
                                                  res_aux = word_list(w_list_copy, remaining_list_copy)
                                                  # Keep only the longest list
                                                  res = res_aux if len(res_aux) > max_result_len else res
                                                  return res

                                                  words = ['giraffe', 'elephant', 'ant', 'tiger', 'racoon', 'cat', 'hedgehog', 'mouse']
                                                  word_list(['dog'], words)


                                                  output:



                                                  ['dog', 'giraffe', 'elephant', 'tiger', 'racoon']






                                                  share|improve this answer












                                                  share|improve this answer



                                                  share|improve this answer










                                                  answered 10 hours ago









                                                  Pedro Torres

                                                  48528




                                                  48528






















                                                      up vote
                                                      1
                                                      down vote













                                                      Hopefully, a more intuitive way of doing it without recursion. Iterate through the list and let Python's sort and list comprehension do the work for you:



                                                      words = ['giraffe', 'elephant', 'ant', 'tiger', 'racoon', 'cat', 'hedgehog', 'mouse']

                                                      def chain_longest(pivot, words):
                                                      new_words =
                                                      new_words.append(pivot)
                                                      for word in words:
                                                      potential_words = [i for i in words if i.startswith(pivot[-1]) and i not in new_words]
                                                      if potential_words:
                                                      next_word = sorted(potential_words, key = lambda x: len)[0]
                                                      new_words.append(next_word)
                                                      pivot = next_word
                                                      else:
                                                      pass
                                                      return new_words

                                                      max([chain_longest(i, words) for i in words], key = len)
                                                      >>
                                                      ['hedgehog', 'giraffe', 'elephant', 'tiger', 'racoon']


                                                      Set a pivot and check for potential_words if they start with your pivot word and do not appear in your new list of words. If found then just sort them by length and take the first element.



                                                      The list comprehension goes through every word as a pivot and returns you the longest chain.






                                                      share|improve this answer























                                                      • The expected output and longest word chain is: ['hedgehog', 'giraffe', 'elephant', 'tiger', 'racoon'], your one gives ['giraffe', 'elephant', 'tiger', 'racoon'] or am I missing something?
                                                        – Mandingo
                                                        10 hours ago






                                                      • 1




                                                        You can replace key = lambda x: len(x) with key=len.
                                                        – Keyur Potdar
                                                        10 hours ago






                                                      • 1




                                                        @mandingo sorry I got confused with the output. Let me change that.
                                                        – BernardL
                                                        10 hours ago















                                                      up vote
                                                      1
                                                      down vote













                                                      Hopefully, a more intuitive way of doing it without recursion. Iterate through the list and let Python's sort and list comprehension do the work for you:



                                                      words = ['giraffe', 'elephant', 'ant', 'tiger', 'racoon', 'cat', 'hedgehog', 'mouse']

                                                      def chain_longest(pivot, words):
                                                      new_words =
                                                      new_words.append(pivot)
                                                      for word in words:
                                                      potential_words = [i for i in words if i.startswith(pivot[-1]) and i not in new_words]
                                                      if potential_words:
                                                      next_word = sorted(potential_words, key = lambda x: len)[0]
                                                      new_words.append(next_word)
                                                      pivot = next_word
                                                      else:
                                                      pass
                                                      return new_words

                                                      max([chain_longest(i, words) for i in words], key = len)
                                                      >>
                                                      ['hedgehog', 'giraffe', 'elephant', 'tiger', 'racoon']


                                                      Set a pivot and check for potential_words if they start with your pivot word and do not appear in your new list of words. If found then just sort them by length and take the first element.



                                                      The list comprehension goes through every word as a pivot and returns you the longest chain.






                                                      share|improve this answer























                                                      • The expected output and longest word chain is: ['hedgehog', 'giraffe', 'elephant', 'tiger', 'racoon'], your one gives ['giraffe', 'elephant', 'tiger', 'racoon'] or am I missing something?
                                                        – Mandingo
                                                        10 hours ago






                                                      • 1




                                                        You can replace key = lambda x: len(x) with key=len.
                                                        – Keyur Potdar
                                                        10 hours ago






                                                      • 1




                                                        @mandingo sorry I got confused with the output. Let me change that.
                                                        – BernardL
                                                        10 hours ago













                                                      up vote
                                                      1
                                                      down vote










                                                      up vote
                                                      1
                                                      down vote









                                                      Hopefully, a more intuitive way of doing it without recursion. Iterate through the list and let Python's sort and list comprehension do the work for you:



                                                      words = ['giraffe', 'elephant', 'ant', 'tiger', 'racoon', 'cat', 'hedgehog', 'mouse']

                                                      def chain_longest(pivot, words):
                                                      new_words =
                                                      new_words.append(pivot)
                                                      for word in words:
                                                      potential_words = [i for i in words if i.startswith(pivot[-1]) and i not in new_words]
                                                      if potential_words:
                                                      next_word = sorted(potential_words, key = lambda x: len)[0]
                                                      new_words.append(next_word)
                                                      pivot = next_word
                                                      else:
                                                      pass
                                                      return new_words

                                                      max([chain_longest(i, words) for i in words], key = len)
                                                      >>
                                                      ['hedgehog', 'giraffe', 'elephant', 'tiger', 'racoon']


                                                      Set a pivot and check for potential_words if they start with your pivot word and do not appear in your new list of words. If found then just sort them by length and take the first element.



                                                      The list comprehension goes through every word as a pivot and returns you the longest chain.






                                                      share|improve this answer














                                                      Hopefully, a more intuitive way of doing it without recursion. Iterate through the list and let Python's sort and list comprehension do the work for you:



                                                      words = ['giraffe', 'elephant', 'ant', 'tiger', 'racoon', 'cat', 'hedgehog', 'mouse']

                                                      def chain_longest(pivot, words):
                                                      new_words =
                                                      new_words.append(pivot)
                                                      for word in words:
                                                      potential_words = [i for i in words if i.startswith(pivot[-1]) and i not in new_words]
                                                      if potential_words:
                                                      next_word = sorted(potential_words, key = lambda x: len)[0]
                                                      new_words.append(next_word)
                                                      pivot = next_word
                                                      else:
                                                      pass
                                                      return new_words

                                                      max([chain_longest(i, words) for i in words], key = len)
                                                      >>
                                                      ['hedgehog', 'giraffe', 'elephant', 'tiger', 'racoon']


                                                      Set a pivot and check for potential_words if they start with your pivot word and do not appear in your new list of words. If found then just sort them by length and take the first element.



                                                      The list comprehension goes through every word as a pivot and returns you the longest chain.







                                                      share|improve this answer














                                                      share|improve this answer



                                                      share|improve this answer








                                                      edited 10 hours ago

























                                                      answered 10 hours ago









                                                      BernardL

                                                      1,933828




                                                      1,933828












                                                      • The expected output and longest word chain is: ['hedgehog', 'giraffe', 'elephant', 'tiger', 'racoon'], your one gives ['giraffe', 'elephant', 'tiger', 'racoon'] or am I missing something?
                                                        – Mandingo
                                                        10 hours ago






                                                      • 1




                                                        You can replace key = lambda x: len(x) with key=len.
                                                        – Keyur Potdar
                                                        10 hours ago






                                                      • 1




                                                        @mandingo sorry I got confused with the output. Let me change that.
                                                        – BernardL
                                                        10 hours ago


















                                                      • The expected output and longest word chain is: ['hedgehog', 'giraffe', 'elephant', 'tiger', 'racoon'], your one gives ['giraffe', 'elephant', 'tiger', 'racoon'] or am I missing something?
                                                        – Mandingo
                                                        10 hours ago






                                                      • 1




                                                        You can replace key = lambda x: len(x) with key=len.
                                                        – Keyur Potdar
                                                        10 hours ago






                                                      • 1




                                                        @mandingo sorry I got confused with the output. Let me change that.
                                                        – BernardL
                                                        10 hours ago
















                                                      The expected output and longest word chain is: ['hedgehog', 'giraffe', 'elephant', 'tiger', 'racoon'], your one gives ['giraffe', 'elephant', 'tiger', 'racoon'] or am I missing something?
                                                      – Mandingo
                                                      10 hours ago




                                                      The expected output and longest word chain is: ['hedgehog', 'giraffe', 'elephant', 'tiger', 'racoon'], your one gives ['giraffe', 'elephant', 'tiger', 'racoon'] or am I missing something?
                                                      – Mandingo
                                                      10 hours ago




                                                      1




                                                      1




                                                      You can replace key = lambda x: len(x) with key=len.
                                                      – Keyur Potdar
                                                      10 hours ago




                                                      You can replace key = lambda x: len(x) with key=len.
                                                      – Keyur Potdar
                                                      10 hours ago




                                                      1




                                                      1




                                                      @mandingo sorry I got confused with the output. Let me change that.
                                                      – BernardL
                                                      10 hours ago




                                                      @mandingo sorry I got confused with the output. Let me change that.
                                                      – BernardL
                                                      10 hours ago










                                                      up vote
                                                      1
                                                      down vote













                                                      I have a tree-based approach for this question which might be faster. I am still working on implementation of the code but here is what I would do:



                                                          1. Form a tree with the root node as first word. 
                                                      2. Form the branches if there is any word or words that starts
                                                      with the alphabet with which this current word ends.
                                                      3. Exhaust the entire given list based on the ending alphabet
                                                      of current word and form the entire tree.
                                                      4. Now just find the longest path of this tree and store it.
                                                      5. Repeat steps 1 to 4 for each of the words given in the list
                                                      and print the longest path among the longest paths we got above.


                                                      I hope this might give a better solution in case there is a large list of words given. I will update this with the actual code implementation.






                                                      share|improve this answer

























                                                        up vote
                                                        1
                                                        down vote













                                                        I have a tree-based approach for this question which might be faster. I am still working on implementation of the code but here is what I would do:



                                                            1. Form a tree with the root node as first word. 
                                                        2. Form the branches if there is any word or words that starts
                                                        with the alphabet with which this current word ends.
                                                        3. Exhaust the entire given list based on the ending alphabet
                                                        of current word and form the entire tree.
                                                        4. Now just find the longest path of this tree and store it.
                                                        5. Repeat steps 1 to 4 for each of the words given in the list
                                                        and print the longest path among the longest paths we got above.


                                                        I hope this might give a better solution in case there is a large list of words given. I will update this with the actual code implementation.






                                                        share|improve this answer























                                                          up vote
                                                          1
                                                          down vote










                                                          up vote
                                                          1
                                                          down vote









                                                          I have a tree-based approach for this question which might be faster. I am still working on implementation of the code but here is what I would do:



                                                              1. Form a tree with the root node as first word. 
                                                          2. Form the branches if there is any word or words that starts
                                                          with the alphabet with which this current word ends.
                                                          3. Exhaust the entire given list based on the ending alphabet
                                                          of current word and form the entire tree.
                                                          4. Now just find the longest path of this tree and store it.
                                                          5. Repeat steps 1 to 4 for each of the words given in the list
                                                          and print the longest path among the longest paths we got above.


                                                          I hope this might give a better solution in case there is a large list of words given. I will update this with the actual code implementation.






                                                          share|improve this answer












                                                          I have a tree-based approach for this question which might be faster. I am still working on implementation of the code but here is what I would do:



                                                              1. Form a tree with the root node as first word. 
                                                          2. Form the branches if there is any word or words that starts
                                                          with the alphabet with which this current word ends.
                                                          3. Exhaust the entire given list based on the ending alphabet
                                                          of current word and form the entire tree.
                                                          4. Now just find the longest path of this tree and store it.
                                                          5. Repeat steps 1 to 4 for each of the words given in the list
                                                          and print the longest path among the longest paths we got above.


                                                          I hope this might give a better solution in case there is a large list of words given. I will update this with the actual code implementation.







                                                          share|improve this answer












                                                          share|improve this answer



                                                          share|improve this answer










                                                          answered 5 hours ago









                                                          CodeHunter

                                                          861324




                                                          861324






















                                                              Mandingo is a new contributor. Be nice, and check out our Code of Conduct.










                                                               

                                                              draft saved


                                                              draft discarded


















                                                              Mandingo is a new contributor. Be nice, and check out our Code of Conduct.













                                                              Mandingo is a new contributor. Be nice, and check out our Code of Conduct.












                                                              Mandingo is a new contributor. Be nice, and check out our Code of Conduct.















                                                               


                                                              draft saved


                                                              draft discarded














                                                              StackExchange.ready(
                                                              function () {
                                                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53485052%2flongest-word-chain-from-a-list-of-words%23new-answer', 'question_page');
                                                              }
                                                              );

                                                              Post as a guest















                                                              Required, but never shown





















































                                                              Required, but never shown














                                                              Required, but never shown












                                                              Required, but never shown







                                                              Required, but never shown

































                                                              Required, but never shown














                                                              Required, but never shown












                                                              Required, but never shown







                                                              Required, but never shown







                                                              Popular posts from this blog

                                                              How did Captain America manage to do this?

                                                              迪纳利

                                                              南乌拉尔铁路局