I've already put a lot of work into this problem and am really near the tail end. The overall goal was to create min length word ladders between two five letter words where each 'rung' of the ladder is one letter different from the previous word. For example:
[heads, heals, hells, halls, hails, tails]
The program starts where you must input a beginning and end word and the length of the ladder you want, and the program must solve it. I've gotten pretty far already, so I'll spare much of the details to explain my current situation.
Say I'm going from "babes" to "child" and I'm looking for a 10 letter word ladder.
I have many thousand pairs of words, where the two pairs are one letter different from eachother. Here is just a small sample of some of the pairs.
[(bares, babes), (banes, babes), (bates, babes), (babel, babes), (bases, babes), (bales, babes)...] etc.
This goes on for a long time, but it is guaranteed in there that my destination word exists, and that there is a path between my starting word (babes) and my ending word (child) is in there, and that ladder is 10 words long.
How do I accomplish this?
EDIT: I have already implemented a graph, and am using BFS to go from the starting to ending word, which works.
public List<T> minLengthPath(T src, T dest, int length)
{
T start = src;
Deque<T> queue = new LinkedList<T>(); //Holds items to visit
Queue<List<T>> ladder = new LinkedList<List<T>>(); //Holds all the ladders?
Set<T> checker = new HashSet<T>(); //Holds visited items
queue.add(start);
checker.add(start);
while(!queue.isEmpty()){
T slot = queue.remove();
if(slot.equals(dest))
{
System.out.println(slot);
return null; //Should be returning ladder
}
Set<Pair<Integer, T>> thing = this.edges.get(slot);
Set<T> edges = findEdges(thing); //Returns the edges of the node
Iterator<T> check = edges.iterator();
for(int a = 0; a < edges.size(); a ++)
{
T hole = check.next();
if(!checker.contains(hole))
{
checker.add(hole);
queue.add(hole);
}
}
}
return null;
}
Word Ladder. A transformation sequence from word beginWord to word endWord using a dictionary wordList is a sequence of words beginWord -> s1 -> s2 -> ... -> sk such that: Every adjacent pair of words differs by a single letter. Every si for 1 <= i <= k is in wordList .
For example, start with CAT. Replacing one letter at a time, the ladder for cat can become: cat – cot – dot – dog. This is a word ladder that starts at "cat" and ends at "dog."
Well, You are describing a graph problem which is known as the shortest path problem.
In here, your graph is G = (V,E)
, where V = { all words}
and E = {(u,v) | there is a direct "ladder" from word u to word v}
.
In this case, the graph is unweighted, so you can use a BFS to find the shortest path from the source to the target.
One can also use A* algorithm for it, after finding an admissible heuristic function that evaluates how far are you from the target node. As noted by @trutheality, one possible heuristic function is the number of mismatched letters.
Note that you don't actually need to "create" the whole graph before you start the search, you can generate it "on the fly" using a function: next(w) = { u | (w,u) is in E, or in other words - there is a direct ladder from w to u }
After finding what is the length of the shortest path by running a BFS, you can also find what exactly the path was - by going back. This thread explains this issue with more details. The idea is maintaining a Map - where the key is the vertex, and the value is how this vertex was discovered - the vertex that led to discovering the key. After the BFS is done, you only need to go from the target back to the source, and you got your path! [reversed, of course...]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With