Consonant clusters help in Pig Latin Algorithm


#1

I have been working on the Pig Latin algorithm challenge today and was able to get all tests to pass except for one -- the consonant cluster. I avoided using Regex in my solution, and I'm curious if there is a way to finish solving this without using it. Here is my code:

function translatePigLatin(str) {
	if (str.charAt(0) === 'a' || str.charAt(0) === 'e' || str.charAt(0) === 'i' || str.charAt(0) === 'o' || str.charAt(0) === 'u') {
		str += "way";
	} else {
		str = str.substr(1) + str.substr(0, 1) + "ay";
	}
 return str;
}
translatePigLatin("consonant");

#2

This is my very ugly code. I didn't use regular expressions, though.
The thing is I missed the part about clusters at first, and then I had to change my code unexpectedly to account for them.
This solution works, but I am still a newbie, so don't take "best practices" from it. :slight_smile:

function translatePigLatin(str) {
  var letters = str.split("");
  var vowels = ["a", "e", "i", "o", "u", "y"];
  var firstVowelIndex;
  var result;
  
  for (var i = 0; i < letters.length; i++) {
    if (vowels.indexOf(letters[i]) !== -1) {
        firstVowelIndex = i;
        break;
        } else {
          continue;
        }
  }
  
  switch(letters[0]) {
    case "a":
    case "e":
    case "i":
    case "o":
    case "u":
    case "y":
      letters.push("way");
      result = letters.join("");
      break;
    default:
      var extractArr = letters.slice(0, firstVowelIndex);
      var extractStr = extractArr.join("");
      letters.push(extractStr);
      var almostDone = letters.slice(firstVowelIndex);
      almostDone.push("ay");
      result = almostDone.join("");
  } 
  
  return result;

#3

Since you need to remove a cluster of consonants, just use a for loop till you find a vowel, then split from that position, using the same line of code you're using in the else statement. Just replace "1" in str.substr(1, str.length) in your code with the correct position and it works!

So if you get a vowel at position 3 (or index 2 with 0 indexing) then the answer is str= str.substr(2, str.length)+ str.substr(0, 2) + "ay".

Here's a working example of a modified version of your code:

function translatePigLatin(str) {
	if (str.charAt(0) === 'a' || 
            str.charAt(0) === 'e' || 
            str.charAt(0) === 'i' || 
            str.charAt(0) === 'o' || 
            str.charAt(0) === 'u') {
               str += "way";
	} 
        else {
            //vowelpos is the position of first vowel we encounter
            var vowelpos=-1;
            for(var i=1; i<str.length; i++){
                if(str.charAt(i) === 'a' || 
                   str.charAt(i) === 'e' || 
                   str.charAt(i) === 'i' || 
                   str.charAt(i) === 'o' || 
                   str.charAt(i) === 'u'){
                       //find vowel and break
                       vowelpos= i;  
                       break;
                }
 
            }
           //start from vowelpos to end, then append the rest with "ay"
	   str = str.substr(vowelpos, str.length) + str.substr(0, vowelpos) + "ay";
    }
    return str;
}
translatePigLatin("consonant");

If you're interested in my solution, which involves a very simple regex, here you go:

function translatePigLatin(str) {
  var re=/[aeiou]/i;
  var val= str.split("").indexOf(str.match(re)[0]);
  var postfix= val===0? "way":"ay";
  str= str.substring(val, str.length)+
       str.substring(0, val)+postfix;
  
  return str;
}

translatePigLatin("algorithm");

#4

That is exactly what I was looking for, thank you! I figured there was a way to use a for loop to run through that, but I didn't even think to set a variable to -1 first. I like the looks of your Regex solution -- it is much more elegant. I'll have to solve it the Regex way on my own next.


#5

Very nice! It looks like you made use of all of the suggestions on the algorithm page, and that's really cool. I made the same mistake in overlooking the consonant cluster criteria too :grin:


#6

This is how I went about it:

function translatePigLatin(str) {
  var firstVowel = str.indexOf(str.match(/[aeiou]/i));
  
  if (firstVowel === 0) return str + 'way';
  return str.slice(firstVowel) + str.slice(0, firstVowel) + 'ay';
}

#7

That is very succinct. I like your solution a lot!


#8

Hi. This is my solution.

function translatePigLatin(str) {
  if (/^[aeiou]/i.test(str)) return str + 'way';
  
  const leadConsonants = /^[^aeiou]+/i.exec(str)[0];
  return str.slice(leadConsonants.length) + leadConsonants + 'ay';
}

#9

@P1xt Everything you code seems to be truly gold. I believe you are a genius! :slight_smile:


#10

How about this solution is it OK?
function translatePigLatin(str) {
var arr=["a","e","i","o","u","A","E","I","O","U"];
var smallstr="";
if (arr.indexOf(str.charAt(0))>=0){return str.concat("way");}
else
{
var bool=true;
var i=0;

while (bool){
  if (arr.indexOf(str.charAt(i))<0)
    { 
      smallstr+=str.charAt(i);
      i++;
      bool =true;
    }
  else{
    bool = false;
  }

}
 return str.substr(i,str.length).concat(smallstr).concat("ay");

}

}


#11

exactly… I love to compare my code with his and try to learn his methods. He is really good.


#12

@P1xt is using and showing the power of Regular Expression :slight_smile:
and how lines of code can be reduced if we use Regular Expression appropriately


#13

This is a useful resource for regular expressions if anyone is interested: https://regexr.com/