|
1 |
| -# Assignment 2 |
2 |
| -The greek version of the assignment description is found [here](https://github.com/dmst-algorithms-course/assignment-2019-2/blob/master/assignment_2019_2.ipynb) |
| 1 | +# Broken Telephone |
| 2 | +Everyone has played the game broken telephone, where one player starts whispering a word to another and then that player to another and so on. The last player calls out the word and it is usually completely different to the starting word. |
| 3 | + |
| 4 | +Based on that principle, we want to build a script that showcases how words can be altered in order to start from one word move on to new words and finally reach a target word, with the least number of steps. At each step, we want the current word to differ to the next one by just one letter: |
| 5 | +* Either deleting one letter |
| 6 | +* Or inserting one letter |
| 7 | +* Or changing one letter |
| 8 | + |
| 9 | +For example, let's say we want to go from the word spring to the word summer. The modifications would be: |
| 10 | + |
| 11 | + spring -> string -> sting -> ting -> tine -> time -> timer -> dimer -> dimmer -> simmer -> summer |
| 12 | + |
| 13 | +To solve the problem, we can visualize it as a huge graph, where each word is node. Two words are connected if they vary by one letter, as explained in the above rule. The solution would be to find the quickest path between two words of the graph. |
| 14 | + |
| 15 | +However, we do not need to construct the whole graph in order to solve the problem. We only need a way to detect the neighbors of a word, meaning other words that differ by one letter only |
| 16 | + |
| 17 | +## Levenshtein Distance |
| 18 | +The first step in this approach is to find a way of measuring how different two words are, so that we can know if two words are different by one insertion, deletion, or spelling. The metric that gives us exactly the number of insertions, deletions, or letter changes required to convert one word to another is called [Levenshtein distance](https://en.wikipedia.org/wiki/Levenshtein_distance). |
| 19 | + |
| 20 | +## BK trees |
| 21 | +The second step in solving our problem is to find an effective way to dynamically locate the neighbors of each word. One such way is the data structure called the [BK-tree](https://en.wikipedia.org/wiki/BK-tree). A BK tree is defined as follows: |
| 22 | +* We select any element as a root. |
| 23 | +* Each node of the tree can have as many children, even `n`, corresponding to `n` subtrees. The `k` subtree of a node contains elements that have a distance from the node equal to `k`. |
| 24 | + |
| 25 | +The process is decribed by the following algorithm: |
| 26 | + |
| 27 | +<p align="center"> |
| 28 | +<img src="https://github.com/stef4k/Algorithms-and-data-structures-assignments/blob/main/assignment-2/images/bk_tree_insertion_algorithm.png" width="500" height="300" /> |
| 29 | +</p> |
| 30 | + |
| 31 | +Also, the search process is described by the following algorithm: |
| 32 | + |
| 33 | +<p align="center"> |
| 34 | +<img src="https://github.com/stef4k/Algorithms-and-data-structures-assignments/blob/main/assignment-2/images/bk_tree_search_algorithm.png" width="500" height="450" /> |
| 35 | +</p> |
| 36 | + |
| 37 | +## Finding the path |
| 38 | +The third step in the approach is to find the path in the graph. This can be done with a modification of the Dijkstra algorithm. As with the normal algorithm, we maintain a priority queue that we use to see which node we will visit. But instead of the priority of the nodes in the queue arising from the distance from the node we started, it will result from the sum of the distance from the node we started and the distance to the destination node. Then we actually get another search algorithm, the [algorithm A *](https://en.wikipedia.org/wiki/A*_search_algorithm). |
| 39 | + |
| 40 | +## Installation requirements |
| 41 | +Install the necessary library: |
| 42 | + |
| 43 | + pip install Levenshtein |
| 44 | + |
| 45 | +## Running the script: |
| 46 | +Run the script from the command line: |
| 47 | + |
| 48 | + python word_morph.py <dictionary_file> <start_word> <target_word> |
| 49 | + |
| 50 | +In the command, <dictionary_file> is the dictionary we want to use. The parameter <start_word> is the word we want to start and <target_word> is the word we want to reach. |
| 51 | + |
| 52 | +If there is no way to reach the <target_word> from the <start_word>, the output should be: |
| 53 | + |
| 54 | + start_word |
| 55 | + |
| 56 | +## Examples |
| 57 | +### Example 1 |
| 58 | +If the user runs the script in the following way: |
| 59 | + |
| 60 | + python word_morph.py dictionary.txt life death |
| 61 | + |
| 62 | +The output could be: |
| 63 | + |
| 64 | + life, lift, left, heft, heat, heath, death |
| 65 | + |
| 66 | +### Example 2 |
| 67 | +If the user runs the script in the following way: |
| 68 | + |
| 69 | + python word_morph.py dictionary.txt day night |
| 70 | + |
| 71 | +The output could be: |
| 72 | + |
| 73 | + day, dam, dim, din, sin, sign, sigh, nigh, night |
| 74 | + |
| 75 | +### Example 3 |
| 76 | +If the user runs the script in the following way: |
| 77 | + |
| 78 | + python word_morph.py dictionary.txt reject ratify |
| 79 | + |
| 80 | +The output could be: |
| 81 | + |
| 82 | + reject, resect, reset, rest, pest, past, pasty, party, parity, rarity, rarify, ratify |
| 83 | + |
| 84 | + |
| 85 | +## |
| 86 | +[Complete Greek Assignment Description](https://github.com/dmst-algorithms-course/assignment-2019-2/blob/master/assignment_2019_2.ipynb) |
0 commit comments