I am trying to design a recursive solution to Lewis Carroll's 'Word Ladder' game
The game attempts to link a starting word, for example 'WET' to an ending word, e.g. 'DRY' using a chain of words where between any 2 words just 1 letter is different. There is a limit on how many words can be used to make the chain.
For example for WET - DRY the solution is WET - bet - bat - bay - day - DRY
I am using the below recursive C function
- exit condition: word is 1 step away from the 'target word' - i.e. if it sees DAY (= 1 step away from DRY), it returns true
- It finds the solution, however, the problem is: it does not pass the solution back to original function. With each return call, the chain shaves off one word - i.e. the function's innermost call correctly solves 'bet - bat - bay - day' and stores it in the
answer_chain
- however once calls unwind - this array somehow gets passed as 'bet - bat - bay' (=loses 1 word), and so on, and as a result the original outermost function call gets no information about the solution.
I've tried:
- Copying 'by value' by creating a c-style string first, assigning it back later
- Copying the array item-by-item only when the first return is reached, and just assigning one array to the other otherwise (
answer_chain = answer_chain_temp
)
I've unfortunately not been able to figure out what the issue actually is.
Any help would be greatly appreciated.
bool find_chain(const char* start_word, const char* target_word, const char* answer_chain[], int max_steps){
if (answer_chain[0] == NULL) {} // This is to zero out incoming answer_chain
else if (!valid_step(start_word,answer_chain[0])){
delete[] answer_chain;
for (unsigned int i = 0; i < sizeof(answer_chain)/sizeof(answer_chain[0]);++i){
answer_chain[i] = NULL;
}
}
int filled_words = find_sz_of_char_arrays(answer_chain); // Looks for null-terminator
string previous_word, try_new_word;
bool is_solved = false;
if (valid_chain(answer_chain) && valid_step(answer_chain[filled_words-1],target_word) ) {
is_solved = true;
}
if (is_solved) {return true;}
if (max_steps == 0 && !is_solved) {return false;}
if (filled_words > 0) { previous_word = answer_chain[filled_words-1];} else {previous_word = start_word;}
for (unsigned int j = 0; j < strlen(start_word); ++j){
try_new_word = previous_word;
for (unsigned int i = 0; i < 26; ++i){
char new_char = i + 'A';
if (try_new_word.at(j) != new_char) { // has to be different from character already in place
try_new_word.at(j) = new_char;
if (valid_step(previous_word.c_str(),try_new_word.c_str()) && !is_word_already_in_chain(try_new_word.c_str(),answer_chain) ) {
const char** answer_chain_temp = new const char*[15]; // append 'try' word to answer array
for (int k = 0; k < filled_words;++k){
answer_chain_temp[k] = answer_chain[k];}
answer_chain_temp[filled_words] = try_new_word.c_str();
answer_chain_temp[filled_words+1] = NULL;
if (find_chain(start_word,target_word,answer_chain_temp,max_steps-1)){
delete[] answer_chain;
answer_chain = new const char*[15];
for (int kk = 0; kk < 15;++kk) {
if (answer_chain_temp[kk]!=NULL){
answer_chain[kk] = answer_chain_temp[kk];
}
}
delete[] answer_chain_temp;
return true;
} // if successful - append the word
} // if valid step
} // if letter is differerent
} // for i
} // for j
return false;
}
EDIT: I've now changed the middle part to copy the .s_str() by value, however the issue still seems to persist. I believe something is off with how I am copying and deleting after the solution has been found:
const char** answer_chain_temp = new const char*[15]; // append 'try' word to answer array
for (int k = 0; k < filled_words;++k){answer_chain_temp[k] = answer_chain[k];}
char * writable = new char[try_new_word.size() + 1];
std::copy(try_new_word.begin(), try_new_word.end(), writable);
writable[try_new_word.size()] = '\0';
answer_chain_temp[filled_words] = writable;
answer_chain_temp[filled_words+1] = NULL;
if (find_chain(start_word,target_word,answer_chain_temp,max_steps-1)){
delete[] answer_chain;
answer_chain = new const char*[15];
for (int kk = 0; kk < 15;++kk) {
if (answer_chain_temp[kk] != NULL){
answer_chain[kk] = answer_chain_temp[kk]; // <<<<<< I believe the problem is here
}
}
display_chain(answer_chain,cout); cout << endl;
delete[] answer_chain_temp;
return true;```