I'm stuck in Mutations (Basic Algorithm Scripting)

Here is the problem is known as Mutations from javascript algorithm and data-structures Certification Curriculum.
Here is my code:

function mutation(arr) {
  var one = arr[0].toUpperCase().split("");
  console.log(one);
  var two = arr[1].toUpperCase().split("");
  console.log(two)
  var count = 0;
  for(let i= 0; i < two.length; i++){
    for(let j= 0; j < one.length; j++){
      if(one[j] === two[i]){
          count += 1;
      }
    }
  }
  if(count >= two.length){
    return true;
  } else{
    return false
  }
}
console.log(mutation(["voodoo", "no"]));

Output:

// running tests
mutation(["voodoo", "no"]) should return false.
[ 'V', 'O', 'O', 'D', 'O', 'O' ]
[ 'N', 'O' ]

I understand why it’s happening but can’t figure out a better way to fix this.
Can you please give me some suggestion to improve my way of thinking?

You get wrong results because you count the same letter every time it appears.

In the voodoo example the count is going to be 4 (4 x “o”), so it is larger than length of “no”.

I suggest you keep track only of one variable for example “result” that is initialized to true. If you find a letter that doesn’t exist then you change it to false.

Hope it helps, good luck :wink:

1 Like

Thank you so much :heart:
Finally, I got it :confused:
Here is my code:

function mutation(arr) {
  function helper(a,li){
    var count = 0;
    for(let i=0; i < li.length; i++){
      if(a === li[i]){
        count += 1;
      }
    }
    if(count === 0){
      return false;
    }else{
      return true;
    }
  }
  var one = arr[0].toUpperCase().split("");
  var two = arr[1].toUpperCase().split("");
  var count = 0;
  for(let i= 0; i < two.length; i++){
    if(helper(two[i],one) !== true){
      count += 1;
    }
  }
  if(count === 0){
    return true;
  } else{
    return false;
  }
}

Any suggestion to make it better?

First of all, try not to mix var and let, if you haven’t got really good reason to use var just use let and const :slight_smile:

Back to the logic of your function. Take a look at this example:

const animals = ['dog', 'horse', 'cat', 'cat', 'zebra'];

function isThereCat(arr) {
  // Initially the result is false because we assume that there
  // will be no cat
  let result = false;
  
  for (let i = 0; i < arr.length; i++) {
    if (arr[i] === 'cat') {
      // If we find the cat, then we set the result to false
      result = true;
    }
  }
  
  return result;
}

What I’m trying to say is that you don’t need the “count”. In the example function the fact that there are two cats doesn’t change the final result.

The same applies in this challenge. We only care if all the letters from one word can be found in another. So as soon as we find one letter that doesn’t exist in another, we know that the function should return false.

I hope it is a little bit more clear now :slight_smile:

1 Like

Like this? :grin:

function mutation(arr) {
  function helper(a,li){
    let result = false;
    for(let i=0; i < li.length; i++){
      if(a === li[i]){
        result = true;
      }
    }
    return result;
  }
  const one = arr[0].toUpperCase().split("");
  const two = arr[1].toUpperCase().split("");
  let result = true;
  for(let i= 0; i < two.length; i++){
    if(helper(two[i],one) !== true){
      result = false;
    }
  }
  return result;
}

As a rule of thumb

  • Use const if you can
  • Use let if you must
  • Never use var
3 Likes

Exactly! Now, your helper function is very similar to one method that already for Strings and Arrays.

String.prototype.includes()
Array.prototype.includes()

Example usage:

const word = "wolf";

word.includes("f");
// → true
word.includes("m");
// → false

If you want you can give it a try and use it instead of your helper function :slight_smile:

1 Like

Thank you so much. It was a great lesson. It’s cleaner :heart_eyes: :partying_face:

function mutation(arr) {
  const one = arr[0].toUpperCase().split("");
  const two = arr[1].toUpperCase().split("");
  let result = true;
  for(let i= 0; i < two.length; i++){
    if(one.includes(two[i]) !== true){
      result = false;
    }
  }
  return result;
}
1 Like