I have tried it with the following:
1. Finding only the first instance of a word
2. Finding multiple instances of the same word (e.g. home in the array three times)
3. All directions
4. Overlapping words
5. Bigger arrays with more words
6. Single words
7. No words
Please excuse my verbose code, I was trying to avoid huge loops and if statements by making it as modular as I could.
Does anyone know specifically WHAT conditions we are meant to do to pass this?
Thank you kindly, BJB.
package com.codegym.task.task20.task2027;
import java.util.ArrayList;
import java.util.List;
/*
Expected result
home - (5, 3) - (2, 0)
same - (1, 1) - (4, 1)
/*Expected result
[usa - (0, 1) - (2, 1), poeeaa - (0, 4) - (5, 4), nasa - (4, 6) - (4, 9), qsa - (3, 8) - (5, 8)]
*/
public class Solution {
public static void main(String[] args) {
int[][] wordSearch = new int[][]{
{'h', 'd', 'e', 'e', 'l', 'k'},
{'o', 's', 'a', 'm', 'e', 'o'},
{'m', 'n', 'g', 'a', 'o', 'v'},
{'e', 'a', 'p', 's', 'r', 'h'},
{'p', 's', 'e', 'e', 'j', 'j'}
};
System.out.println(detectAllWords(wordSearch, "home", "same"));
}
public static List<Word> detectAllWords(int[][] wordSearch, String... words) {
List<Word> wordsFound = new ArrayList<>();
//Go through each word
for (String s : words) {
int firstChar = s.charAt(0);
Word currentWord = null;
for (int y = 0; y < wordSearch.length; y++) {
//if (currentWord != null) break; //###use this if you want to find only one instance of word. Disable if you want to find all instances
for (int x = 0; x < wordSearch[y].length; x++) {
if (wordSearch[y][x] == firstChar) {
//found first letter so see if can make full word
if ((currentWord = findWord(y, x, s, wordSearch)) != null) {
wordsFound.add(currentWord);
}
}
}
}
}
if (wordsFound.size() > 0) {
return wordsFound;
} else {
return null;
}
}
public static Word findWord(int y, int x, String wordToFind, int[][] wordSearch) { //if found word then return word details or return null
Word currentWord = new Word(wordToFind); //current word we are trying to find
currentWord.startY = y;
currentWord.startX = x;
int matchCount = 1;
int moveAmount = 1;
while (checkN(y, x, wordToFind.charAt(moveAmount), wordSearch, moveAmount)) {
moveAmount++; //match is found so move along 1
matchCount++; //match found so add 1 to count
if (matchCount == wordToFind.length() - 1) { //if we have matched every word find [y][x] pos and return complete word
currentWord.endY = y - moveAmount;
currentWord.endX = x;
return currentWord;
}
}
matchCount = 1; //reset counts for next direction check
moveAmount = 1;
while (checkS(y, x, wordToFind.charAt(moveAmount), wordSearch, moveAmount)) {
moveAmount++; //match is found so move along 1
matchCount++; //match found so add 1 to count
if (matchCount == wordToFind.length() - 1) { //if we have matched every word find [y][x] pos and return complete word
currentWord.endY = y + moveAmount;
currentWord.endX = x;
return currentWord;
}
}
matchCount = 1; //reset counts for next direction check
moveAmount = 1;
while (checkE(y, x, wordToFind.charAt(moveAmount), wordSearch, moveAmount)) {
moveAmount++; //match is found so move along 1
matchCount++; //match found so add 1 to count
if (matchCount == wordToFind.length() - 1) { //if we have matched every word find [y][x] pos and return complete word
currentWord.endY = y;
currentWord.endX = x + moveAmount;
return currentWord;
}
}
matchCount = 1; //reset counts for next direction check
moveAmount = 1;
while (checkW(y, x, wordToFind.charAt(moveAmount), wordSearch, moveAmount)) {
moveAmount++; //match is found so move along 1
matchCount++; //match found so add 1 to count
if (matchCount == wordToFind.length() - 1) { //if we have matched every word find [y][x] pos and return complete word
currentWord.endY = y;
currentWord.endX = x - moveAmount;
return currentWord;
}
}
matchCount = 1; //reset counts for next direction check
moveAmount = 1;
while (checkNW(y, x, wordToFind.charAt(moveAmount), wordSearch, moveAmount)) {
moveAmount++; //match is found so move along 1
matchCount++; //match found so add 1 to count
if (matchCount == wordToFind.length() - 1) { //if we have matched every word find [y][x] pos and return complete word
currentWord.endY = y - moveAmount;
currentWord.endX = x - moveAmount;
return currentWord;
}
}
matchCount = 1; //reset counts for next direction check
moveAmount = 1;
while (checkNE(y, x, wordToFind.charAt(moveAmount), wordSearch, moveAmount)) {
moveAmount++; //match is found so move along 1
matchCount++; //match found so add 1 to count
if (matchCount == wordToFind.length() - 1) { //if we have matched every word find [y][x] pos and return complete word
currentWord.endY = y - moveAmount;
currentWord.endX = x + moveAmount;
return currentWord;
}
}
matchCount = 1; //reset counts for next direction check
moveAmount = 1;
while (checkSW(y, x, wordToFind.charAt(moveAmount), wordSearch, moveAmount)) {
moveAmount++; //match is found so move along 1
matchCount++; //match found so add 1 to count
if (matchCount == wordToFind.length() - 1) { //if we have matched every word find [y][x] pos and return complete word
currentWord.endY = y + moveAmount;
currentWord.endX = x - moveAmount;
return currentWord;
}
}
matchCount = 1; //reset counts for next direction check
moveAmount = 1;
while (checkSE(y, x, wordToFind.charAt(moveAmount), wordSearch, moveAmount)) {
moveAmount++; //match is found so move along 1
matchCount++; //match found so add 1 to count
if (matchCount == wordToFind.length() - 1) { //if we have matched every word find [y][x] pos and return complete word
currentWord.endY = y + moveAmount;
currentWord.endX = x + moveAmount;
return currentWord;
}
}
//if no match in any direction return null
return null;
}
public static boolean checkN(int y, int x, int charToFind, int[][] wordSearch, int moveAmount) {
if (y - moveAmount > 0) {
y = y - moveAmount;
} else {
return false;
}
if (wordSearch[y][x] == charToFind) { //check new char at new position matches char we looking for
return true;
} else {
return false;
}
}
public static boolean checkS(int y, int x, int charToFind, int[][] wordSearch, int moveAmount) {
if (y + moveAmount > wordSearch.length - 1) { //check if looking further S will be out of bounds
return false; //if yes return false - we can look no further S
} else {
y = y + moveAmount; //if not set y to new value
}
if (wordSearch[y][x] == charToFind) { //now see if next char S is a match
return true;
} else {
return false;
}
}
public static boolean checkE(int y, int x, int charToFind, int[][] wordSearch, int moveAmount) {
if ((x + moveAmount) > wordSearch[y].length - 1) { //check if looking further E will be out of bounds
return false; //if yes return false - we can look no further E
} else {
x = x + moveAmount; //if not set x to new value
}
if (wordSearch[y][x] == charToFind) { //now see if next char E is a match
return true;
} else {
return false;
}
}
public static boolean checkW(int y, int x, int charToFind, int[][] wordSearch, int moveAmount) {
if (x - moveAmount > 0) { //check if looking further W will be out of bounds
x = x - moveAmount; //if not set X to new value
} else {
return false; //if yes return false - we can look no further W
}
if (wordSearch[y][x] == charToFind) { //now see if next char E is a match
return true;
} else {
return false;
}
}
public static boolean checkNW(int y, int x, int charToFind, int[][] wordSearch, int moveAmount) {
if (x - moveAmount > 0) { //check if looking further NW will be out of bounds
x = x - moveAmount; //if not set X to new value
} else {
return false; //if yes return false - we can look no further W
}
if (y - moveAmount > 0) { //check if looking further NW will be out of bounds
y = y - moveAmount; //if not set Y to new value
} else {
return false; //if yes return false - we can look no further NW
}
if (wordSearch[y][x] == charToFind) { //now see if next char E is a match
return true;
} else {
return false;
}
}
public static boolean checkNE(int y, int x, int charToFind, int[][] wordSearch, int moveAmount) {
if (x + moveAmount > wordSearch[y].length - 1) { //check if looking further NE will be out of bounds
return false; //if yes return false - we can look no further NE
} else {
x = x + moveAmount; //if not set X to new value
}
if (y - moveAmount > 0) { //check if looking further NE will be out of bounds
y = y - moveAmount; //if not set Y to new value
} else {
return false; //if yes return false - we can look no further NE
}
if (wordSearch[y][x] == charToFind) { //now see if next char NE is a match
return true;
} else {
return false;
}
}
public static boolean checkSW(int y, int x, int charToFind, int[][] wordSearch, int moveAmount) {
if (x - moveAmount > 0) { //check if looking further NW will be out of bounds
x = x - moveAmount; //if not set X to new value
} else {
return false; //if yes return false - we can look no further W
}
if (y + moveAmount > wordSearch.length - 1) { //check if looking further NW will be out of bounds
return false; //if yes return false - we can look no further NW
} else {
y = y + moveAmount; //if not set Y to new value
}
if (wordSearch[y][x] == charToFind) { //now see if next char E is a match
return true;
} else {
return false;
}
}
public static boolean checkSE(int y, int x, int charToFind, int[][] wordSearch, int moveAmount) {
if (x + moveAmount > wordSearch[y].length - 1) { //check if looking further NE will be out of bounds
return false; //if yes return false - we can look no further NE
} else {
x = x + moveAmount; //if not set X to new value
}
if (y + moveAmount > wordSearch.length - 1) { //check if looking further NW will be out of bounds
return false; //if yes return false - we can look no further NW
} else {
y = y + moveAmount; //if not set Y to new value
}
if (wordSearch[y][x] == charToFind) { //now see if next char NE is a match
return true;
} else {
return false;
}
}
public static class Word {
private String text;
private int startX;
private int startY;
private int endX;
private int endY;
public Word(String text) {
this.text = text;
}
public void setStartPoint(int i, int j) {
startX = i;
startY = j;
}
public void setEndPoint(int i, int j) {
endX = i;
endY = j;
}
@Override
public String toString() {
return String.format("%s - (%d, %d) - (%d, %d)", text, startX, startY, endX, endY);
}
}
}