Created
July 20, 2012 13:45
-
-
Save benbuckman/3150813 to your computer and use it in GitHub Desktop.
Pig Latin Interpreter in javascript/node.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Pig Latin interpreter | |
by Ben Buckman, July 20 2012 | |
Rules: | |
- All words beginning with a consonant have their first letter moved to the end of word followed by 'ay'. | |
Example: Hello -> Ellohay | |
- All words beginning with a vowel have their first letter moved to the end moved to the word followed by 'hay'. | |
Example: Another -> Notherahay | |
- All punctuation must be kept in place for example: | |
Bacon is awesome! Sometimes, in the morning, I'll have bacon on toast for breakfast. | |
Aconbay sihay wesomeahay! Ometimessay, nihay hetay orningmay, 'llihay avehay aconbay nohay oasttay orfay reakfastbay. | |
*/ | |
var pigLatin = module.exports = function(english) { | |
// make sure it's a string | |
english = '' + english; | |
// (only handle sentences. if paragraphs are expected, can extend this to split on non-space whitespace). | |
var splitWords = english.split(' '), | |
pigLatin = '', | |
splitWordsPigLatin = []; | |
// translate each word | |
splitWords.forEach(function(word){ | |
// starts w/ a consonant or vowel? | |
// word can have an apostrophe in the middle. all other punctuation (comma etc) should be between words. | |
// quotation marks or other punctuation around the word are captured in first block. | |
// i flag indicates case-insensitive | |
var consonantStartPattern = /^[^a-z]*(([bcdfghjklmnpqrstvwxyz]){1}([a-z']*))/i, | |
consonantMatches = word.match(consonantStartPattern), | |
vowelStartPattern = /^[^a-z]*(([aeiou]){1}([a-z']*))/i, | |
vowelMatches = word.match(vowelStartPattern), | |
origWord, rebuiltWord = null; | |
// helper for both scenarios: | |
// want to keep case consistent: if 1st letter is uppercase now, make new 1st letter uppercase. | |
// (matches array is a reference) | |
var consistentCases = function(matches) { | |
if (/[A-Z]/.test(matches[2]) && matches[3].length > 0) { | |
// will be moved to the middle. is the rest of the word uppercase? (maybe it's an acronym) | |
if (matches[3] !== matches[3].toUpperCase()) matches[2] = matches[2].toLowerCase(); | |
matches[3] = matches[3].replace(/^[a-z]{1}/, matches[3][0].toUpperCase()); | |
} | |
}; | |
if (consonantMatches !== null) { | |
/* | |
for '"morning"' [w/quotes], matches will hold: | |
0: '"morning', | |
1: 'morning', | |
2: 'm', | |
3: 'orning', | |
4: index: 0, | |
5: input: '"morning",' | |
*/ | |
// console.log('consonsant matches:', consonantMatches); | |
consistentCases(consonantMatches); | |
origWord = consonantMatches[1]; | |
rebuiltWord = '' + consonantMatches[3] + consonantMatches[2] + 'ay'; // morning => orningmay | |
} | |
else if (vowelMatches !== null) { | |
// console.log('vowel matches:', vowelMatches); | |
// [same match array structure as before] | |
consistentCases(vowelMatches); | |
origWord = vowelMatches[1]; | |
rebuiltWord = '' + vowelMatches[3] + vowelMatches[2] + 'hay'; // Another => Notherahay | |
} | |
if (rebuiltWord) { | |
word = word.replace(origWord, rebuiltWord); | |
} | |
// (if original sentence had multiple spaces between words, this will return those spaces & preserve) | |
splitWordsPigLatin.push(word); | |
}); | |
pigLatin = splitWordsPigLatin.join(' '); | |
return pigLatin; | |
}; | |
// test helper | |
var assertTranslation = function(input, expectedOut) { | |
var assert = require('assert'), | |
actual = pigLatin(input); | |
console.log("Input:\t\t" + input); | |
console.log("Expected:\t" + expectedOut); | |
console.log("Actual:\t\t" + actual); | |
try { | |
assert.equal(actual, expectedOut); | |
console.log("Correct!\n"); | |
return true; | |
} | |
catch(error) { | |
console.error("Incorrect!\n"); | |
return false; | |
} | |
}; | |
assertTranslation('Bacon is awesome! Sometimes, in the morning, I\'ll have bacon on toast for breakfast.', | |
'Aconbay sihay wesomeahay! Ometimessay, nihay hetay orningmay, \'llihay avehay aconbay nohay oasttay orfay reakfastbay.'); | |
// test quotation marks around a word | |
assertTranslation('Sometimes, in the "morning", I eat bacon.', | |
'Ometimessay, nihay hetay "orningmay", Ihay atehay aconbay.'); | |
// test extra whitespace | |
assertTranslation('Sometimes, in the morning', | |
'Ometimessay, nihay hetay orningmay'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment