summaryrefslogtreecommitdiffstats
path: root/lab2/wordchain/src/wordchain.cpp
blob: 74636975782d8835febf05b01868ef0e880bcef0 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include <forward_list>
#include <fstream>
#include <iostream>
#include <queue>
#include <set>
#include <stack>
#include <string>

using namespace std;

const string ALPHABET = "abcdefghijklmnopqrstuvwxyz";

void openDictionary(set<string> &words, string path) {
    ifstream input;
    input.open(path);
    string word;
    while (input >> word) {
        words.insert(word);
    }
    input.close();
}

void getValidNeighbours(forward_list<string> &neighbours, string &word, set<string> &words) {
    for (int i = 0; i < word.length(); i++) {
        string new_word = word;
        char cur_c = word[i];
        for (char new_c: ALPHABET) {
            if (new_c != cur_c) {
                new_word[i] = new_c;
                if (words.count(new_word) != 0) {
                    neighbours.push_front(new_word);
                }
            }
        }
    }
}

void wordchain(stack<string> &chain, string w1, string w2, set<string> &words) {
    stack<string> firstChain;
    firstChain.push(w1);

    queue<stack<string>> chains;
    chains.push(firstChain);

    set<string> seenWords;
    while (!chains.empty()) {
        stack<string> curChain = chains.front();
        chains.pop();
        forward_list<string> validNeighbours;
        getValidNeighbours(validNeighbours, curChain.top(), words);
        for (string &w: validNeighbours) {
            if (w == w2) {
                chain.push(w);
                while (!curChain.empty()) {
                    chain.push(curChain.top());
                    curChain.pop();
                }
                return;
            }
            if (seenWords.count(w) == 0) {
                seenWords.insert(w);
                stack<string> newChain = curChain;
                newChain.push(w);
                chains.push(newChain);
            }
        }
    }
}

int main() {
    cout << "Welcome to TDDD86 Word Chain." << endl;
    cout << "If you give me two English words, I will transform the" << endl;
    cout << "first into the second by changing one letter at a time." << endl;
    cout << endl;

    cout << "Please type two words: ";

    string word1, word2;
    cin >> word1 >> word2;

    cout << "Reading valid words..." << endl;
    set<string> words;
    openDictionary(words, "res/dictionary.txt");
    cout << "Done." << endl;

    cout << "Searching..." << endl;
    stack<string> chain;
    wordchain(chain, word1, word2, words);
    cout << "Done." << endl;

    while (!chain.empty()) {
        cout << chain.top() << " ";
        chain.pop();
    }
    cout << endl;
}