Reputation: 374
I have a list with 794 three-letter long words. My task is to find the word(s) with the longest path to a given word.
Definition (children):
Children to a parent word are the parent word with one and only one letter replaced.
Example:
'can', 'run', 'rap' etcetera are children to the word 'ran' (given that those words exist in the list).
Definition (path):
A path is a series of words where each word is generated by exchanging a single letter in the previous.
#Pseudo code
Given a word
Put the word in a queue
Keep a list with all visited words
As long as the queue is not empty
Get the first word in the queue
Generate a list with all the children to this word
For every children in that list
If the child is not in the list of visited words
Append the child to the list of visited words
Put the child in the queue
Print the path to the last grandchild.
My idea is that this will give the longest path since we continue to generate new children until we run out of possible children (that is, children that hasn't already been visited).
Question:
Is my idea valid? How can I test if it actually works?
The actual code can be viewed below, but it might not make any sense without comments.
Edit
Since trees and lists can be a bit slow, I replaced them with sets.
from Queue import Queuenode; import Bintree
with open('word3',encoding='utf-8') as f:
lista=f.readlines()
lista=[x.strip('\n') for x in lista]
alfabet='abcdefghijklmnopqrstuvwxyzåäö'
class Word:
def __init__(self, w, f = None):
self.word = w
self.parent = f
children=Bintree.Bintree()
for i in lista:
children.put(i)
def barn(far):
barnlista=[]
for i in range(3):
for j in range(29):
empty=''
empty+=far[0:i]+alfabet[j]+far[i+1:]
if empty!=far and children._exists(empty):
barnlista+=[empty]
return barnlista
ko=Queuenode()
def vag(item):
start=item
counter=0
while start!=None:
counter+=1
print(start.word)
start=start.parent
print(counter)
def bfsx(startord):
ko.put(Word(startord))
besokta=[startord]
while not ko.isempty():
first=ko.get()
lista=barn(first.word)
for child in lista:
if child not in besokta:
besokta+=[child]
ko.put(Word(child,first))
vag(first)
Upvotes: 2
Views: 630
Reputation: 76381
IIUC, this is not guaranteed to work (in fact, you can build cases where it doesn't).
Suppose you start at node a; there is a direct path a → b; there are also a direct path a → c and an indirect path c ⇒ b.
Suppose that when you iterate over the children of a, you encounter b before c. You deal with b and mark it as visited. At some point later you encounter c, and eventually reconsider b again. At that point, however, b is already considered visited, so your algorithm will consider the shorter subpath a → b rather than the longer one a → c ⇒ b.
You cannot also get rid of the "visited" mark, as the story behind your graph makes it clear it is not a DAG. If you remove the "visited" logic, you will encounter infinite loops.
Upvotes: 1