1

I am building a simple hangman game using Javascript and wanted to know what the best way to optimise my code would be.

const Hangman = function (word, remainingGuesses) {
  this.word = word.toLowerCase().split("");
  this.remainingGuesses = remainingGuesses;
  this.guessedLetters = [];
};

Hangman.prototype.getPuzzle = function () {
  let puzzle = "";
  this.word.forEach((char) => {
    this.guessedLetters.includes(char) || char === " "
      ? (puzzle += char)
      : (puzzle += "*");
  });
  return puzzle;
};

At the moment as you can see from the above code, I am doing a forEach loop for this.word and then inside the forEach loop I am using .includes() to find whether a word has been guessed, if not then set the char to *.

At the moment I believe the time complexity of O(n2) due to the includes() inside the forEach what would be a better way to rewrite the getPuzzle() function?

1 Answer 1

3

Use a Set for guessedLetters for constant time lookup:

const Hangman = function (word, remainingGuesses) {
  this.word = word.toLowerCase().split("");
  this.remainingGuesses = remainingGuesses;
  this.guessedLetters = new Set(); // this is a Set now
};

Hangman.prototype.getPuzzle = function () {
  let puzzle = "";
  this.word.forEach((char) => {
    // use Set.has instead of Array.includes
    this.guessedLetters.has(char) || char === " "
      ? (puzzle += char)
      : (puzzle += "*");
  });
  return puzzle;
};

You can add a new guessed letter with this.guessedLetters.add(char).

Sign up to request clarification or add additional context in comments.

4 Comments

Yes, using a Set or hash is the right way to go for faster lookups (as opposed to repeated linear searches through an array). BUT, since strings are immutable, your forEach loop is STILL doing a lot of unnecessary work; every use of '+=' has to recreate the entire string over again. To avoid this, change the puzzle variable to an array, change "(puzzle += char)" to "puzzle.push(char)" (same for "*"), and return puzzle.join(''). This means that you build the string only once.
Very interesting and clean solution with the Set. I have one question though, isn't a simple object (map of key and value) even faster? The object would be something like this: { 'a': 'a', 'b': 'b' }, where 'a' and 'b' are the guessed letters.
Sets are generally faster than objects.
I got curious about this comparison because I always thought objects were faster. So I found a benchmark that says that objects are much faster than Sets and Maps. Sadly I couldn't find which operations were used to get those results. measurethat.net/Benchmarks/Show/5364/0/set-vs-object-vs-map

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.