Intermediate Algorithm Scripting: Pig Latin - handling words without vowels

Intermediate Algorithm Scripting: Pig Latin - handling words without vowels
0

#1

Tell us what’s happening:

Hello. I need some help with this test. I can’t pass it, it says “Should handle words without vowels”. I think the information is not enough to figure out this error.

Thanks for the help!

This is the Intermediate Algorithm Scripting: Pig Latin

Translate the provided string to pig latin.

Pig Latin takes the first consonant (or consonant cluster) of an English word, moves it to the end of the word and suffixes an “ay”.

If a word begins with a vowel you just add “way” to the end.

Input strings are guaranteed to be English words in all lowercase.

Remember to use Read-Search-Ask if you get stuck. Try to pair program. Write your own code.

Your code so far


function translatePigLatin(str) {
  if("aeiou".indexOf(str[0]) === -1  ) {
    return str.replace(/(^[b-df-hj-np-tv-z]*)(\w+)/, "$2$1ay" );
  } else {
    return str.concat("way");
    } 
}
translatePigLatin("consonant");

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36.

Link to the challenge:
https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/intermediate-algorithm-scripting/pig-latin


#2

The test Should handle words without vowels. means that your code should work when you get words without vowels. I quickly did a test with your code and if I would take the non existent word: pkljdsk, in pig latin this would be pkljdskay but if I use your code, I get kpkljdsay. Your first letter is wrong.

Edit: This is because they say consonant or consonant cluster, so your full word is one cluster and moves to the back => stays the same. Currently one letter is moved.


#3

Thanks, I already fix it.

function translatePigLatin(str) {
if(!str.match(/[aeiou]/)) {
return str.concat(“ay”);
} else if(“aeiou”.indexOf(str[0]) === -1 ) {
return str.replace(/(^[b-df-hj-np-tv-z]*)(\w+)/, “$2$1ay” );
} else {
return str.concat(“way”);
}
}

translatePigLatin(“consonant”);

It’s messy. I should clean it.

Thanks


#4
function translatePigLatin(str) {
  let j = 0;  // counter for words starting with vowel
  const unmodifiedStr = str;
  for (let i = 0; i < str.length; i++) {
    if (str[i] === 'a' || str[i] === 'e' || str[i] === 'i' || str[i] === 'o' || str[i] === 'u') {
      if (j === 0) {
        return str + "way";
      } else {
        return str + "ay";
      }
      } else {
      str = str.slice(i+1,str.length) + str.slice(0,1);
      i--;
      j = 1;
    }
  }
  return unmodifiedStr;
}

I couldn’t pass the test: “Should handle words without vowels.”


#5

The problem is when you run your test with a word like “rhythm”. Because none of the letters are vowels, the following else is triggered and i never gets beyond 0 (because of your i–).

This creates an infinite loop, because the for loop condition of i < str.length will be true forever.

    } else {
      console.log('here')
      str = str.slice(i+1,str.length) + str.slice(0,1);
      i--;
      j = 1;
    }

#6

This is not an endless loop. my outputs were correct running the tests (functions with parameters) in a jsbin online editor. it’s just that i couldn’t pass the “Should handle words without vowels.” test.

      console.log(str);
      console.log(i);
      str = str.slice(i+1,str.length) + str.slice(0,1);
      console.log(str);
      console.log(i);
      i--;
      console.log(i);
translatePigLatin("california");

output:
“california”
0
“aliforniac”
0
-1

Reason: i needed the var i to be -1 so that when it loops back, var i becomes 0 and evaluates the first “a” of “aliforniac”.

If var i stayed 0 (and when it loops it becomes 1), the “l” will be evaluated in “aliforniac” missing out “a”.


#7

Run the above which is what the last test is testing and you will see an infinite loop. I put a console.log(‘i=’+i) just inside the for loop, so you can see it just keeps looping.


#8

Here’s a better indentation

function translatePigLatin(str) {
  let j = 0;  // counter for words starting with vowel
  const unmodifiedStr = str;
  for (let i = 0; i < str.length; i++) {
    if (str[i] === 'a' || str[i] === 'e' || str[i] === 'i' || str[i] === 'o' || str[i] === 'u') {
      
      // starts with a vowel (without modifying string)
      if (j === 0) {
        return str + "way";
     
     // if first index is a vowel (after modifying string)
      } else {
        return str + "ay";
      }
      
    // if letter is consonant at index 0.
    } else {
      str = str.slice(i+1,str.length) + str.slice(0,1);
      i--;  // return to index 0 until reaching end of str.length
      j = 1;    // to disallow evaluation of first conditional (j === 0) the second time around.
    }
  }
 
 // exit loop, return if no vowels were found.
  return unmodifiedStr;
}


translatePigLatin("rhythm");


#10

Thanks for looking into this.

Here. I removed the str.length. It’s still not passing the last test.

function translatePigLatin(str) {
  let j = 0;  // counter for words starting with vowel
  const unmodifiedStr = str;
  for (let i = 0; i <= 1; i++) {
    if (str[i] === 'a' || str[i] === 'e' || str[i] === 'i' || str[i] === 'o' || str[i] === 'u') {
      
      // starts with a vowel (without modifying string)
      if (j === 0) {
        return str + "way";
     
     // if first index is a vowel (after modifying string)
      } else {
        return str + "ay";
      }
      
    // if letter is consonant at index 0.
    } else {
      str = str.slice(i+1,str.length) + str.slice(0,1);
      i--;  // return to index 0 until reaching end of str.length
      j = 1;    // to disallow evaluation of first conditional (j === 0) the second time around.
    }
  }
 
 // exit loop, return if no vowels were found.
  return unmodifiedStr;
}


translatePigLatin("rhythm");

#11

Hi, can you please explain your regex for the replace function?
Thank you


#12
function translatePigLatin(str) {
  if("aeiou".indexOf(str[0]) > -1){
    return str + "way";
  }else if( str.search(/[aeiou]/) > 0){
    return str.slice(str.search(/[aeiou]/), str.length) + str.slice(0, str.search(/[aeiou]/)) + "ay";
  }else{
    return str + "ay";
  }
}

Hope it helps.


#13

my solve:
did not know how to blurr it out, so I hid the solution in the details tag. :wink:

Summary
function translatePigLatin(str) {
  let myStr = "";
  if (str.match(/^([aeoui])/i) !== null) {
  	myStr = str + 'way';
  }
  else {
  	myStr = str.replace(/([^aeoui]*)(.*)/i, '$2$1');
  	myStr += 'ay';
  }

  return myStr;
}

#14

@Pifko6 and @sebadev Instead of just posting full working solutions, it would be more helpful to the OP to give hints, suggestions, and examples of those hints and suggestions.


#15

@RandellDawson you’re right, my bad. Im at the beginning of my coding adventure and got overexcited, I guess, haha. I will keep it in mind for the future, though.


#17

what does this (.*) do in the expression?


#18

It is a capture group containing .*

The .* means zero more of any character.


#19

okay yes I am aware of what this(*) does but not the this( . )


#20

Okay I just read about it, I get it now thanks


#21

Its interesting the several ways to use regex, be it to look after characters or just test the existence.

I did another way using for but it is not smart enough. Also, thanks for showing .search()

function translatePigLatin(str: string) {
  let regex = /[aeiou]/gi;

  if (regex.test(str[0])) {
    str += "way";
  } else if (str.match(regex)) {
    str = str.replace(/([^aeiou]+)(\w*)/, "$2$1" + "ay");
  }

  if (!regex.test(str)) str += "ay";

  return str;
}

Here is another way.

function translatePigLatin(str: string) {
  let regex = /[aeiou]/gi;

  if (regex.test(str[0])) {
    str += "way";
  } else if (str.match(regex)) {
    str = str.slice(str.search(regex)) + str.slice(0, str.search(regex)) + "ay";
  }

  if (!regex.test(str)) str += "ay";

  return str;
}