3

I am trying to create my own implementation of wordle from scratch in angular and am stuck trying to resolve one of the edge cases. Assume the word to guess for all the following cases is "CLOSE".

CASE 1 - Both duplicate letters are in the wrong position.

If my guess is "CHEER", both of the 'E's are in the wrong position, but "CLOSE" only has one 'E' and hence only one should get a yellow highlight. My code IS dealing with this as desired

case 1

CASE 2 - The letter with the correct position comes first followed by the same letter in the incorrect position

If my guess is "COCKS", the first 'C' is in the correct position and should get a yellow highlight whereas 'C' should get a gray highlight since "CLOSE" only has one 'C'. My code IS dealing with this as desired as well

case 2

CASE 3 - The letter with the incorrect position comes first followed by the same letter in the correct position

If my guess is "LEAVE", the first 'E' is in the incorrect position, but because the second 'E' is in the correct position, and "CLOSE" only has one 'E', it should get a gray highlight and the second 'E' should get a green highlight. This is the edge case that I want to fix

The outcome of my implementation:

case 3

The desired outcome of this case:

desired-coutcome

The logic that I am using at the moment:

let remainingLettersInWord: string = this.chosenWord;

  for (let i = 0; i < 5; i++) {
    if (this.currentGuess[i] === this.chosenWord[i]) {
      remainingLettersInWord = remainingLettersInWord.replace(this.currentGuess[i], '');
      this.setAttributeStyle(i, COLOR.Green);
    } else if (remainingLettersInWord.includes(this.currentGuess[i])) {
      remainingLettersInWord = remainingLettersInWord.replace(this.currentGuess[i], '');
      this.setAttributeStyle(i, COLOR.Yellow);
    } else {
      this.setAttributeStyle(i, COLOR.Gray);
    }
  }

Here, chosenWord = "CLOSE", currentGuess = "CHEER" for case 1, "COCKS" for case 2 and "LEAVE" for case 3

Neeraj Athalye
  • 508
  • 5
  • 26
  • 7
    Start with the green matches and simply remove them completely from both the solution and the guess. That leaves us with "CLOS" and "LEAV". Now the E won't turn yellow because there's no E in "CLOS" (also note that strictly speaking the wordle tag is the only tag that belongs on this question; this is not a JS, angular or typescript problem) –  Mar 02 '22 at 15:12
  • Need some sort of lookahead check when you decide to highlight something yellow? – kelsny Mar 02 '22 at 15:13
  • 1
    Also, you need to factor in the count. Assuming the word is "CLES" and the guess is "LEVE", only the first E is supposed to turn yellow, so you should also remove yellow matches. However the order has to remain intact, so I'd do "CL_S" and "L_VE". Again, the second E will remain grey now because the partial match was removed. –  Mar 02 '22 at 15:19
  • @ChrisG I ended up fixing the problem with your suggestions in mind. Thanks for the help – Neeraj Athalye Mar 02 '22 at 16:26
  • See also: https://stackoverflow.com/q/71617350/7328782 – Cris Luengo Oct 24 '22 at 22:23

2 Answers2

3

I ended up fixing the problem with the help of one of my senior devs and the comment from @Chris G

Here is the solution I used:

let remainingLettersInWord: string = this.chosenWord;

  for (let i = 0; i < 5; i++) {
    if (this.currentGuess[i] === this.chosenWord[i]) {
      remainingLettersInWord = remainingLettersInWord.replace(this.currentGuess[i], '');
      this.setAttributeStyle(i, COLOR.Green);
    } else {
      this.setAttributeStyle(i, COLOR.Gray);
    }
  }

  for (let i = 0; i < 5; i++) {
    if (remainingLettersInWord.includes(this.currentGuess[i]) && this.currentGuess[i] !== this.chosenWord[i]) {
      remainingLettersInWord = remainingLettersInWord.replace(this.currentGuess[i], '');
      this.setAttributeStyle(i, COLOR.Yellow);
    }
  }

I split the logic for the yellow check into a separate loop and I am removing the green words from the list before checking the yellow list. That adheres to all my edge cases now

Neeraj Athalye
  • 508
  • 5
  • 26
2

A different approach by counting the letters of the wanted word.

const
    getColors = ([...word], [...input]) => {
        const
            count = {},
            result = Array(5).fill('-'); // only to show the result.

        for (let i = 0; i < input.length; i++) {
            if (word[i] === input[i]) result[i] = 'green';
            else count[word[i]] = (count[word[i]] || 0) + 1;
        }
        for (let i = 0; i < input.length; i++) {
            if (word[i] === input[i] || !count[input[i]]) continue;
            count[input[i]]--;
            result[i] = 'yellow';
        }
        return result;
    };

console.log(...getColors("CLOSE", "CHEER"));
console.log(...getColors("CLOSE", "COCKS"));
console.log(...getColors("CLOSE", "LEAVE"));
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392