Exercism - Pig Latin
This post shows you how to get Pig Latin exercise of Exercism.
Preparation
Before we click on our next exercise, let’s see what concepts of DART we need to consider

So we need to use the following concepts.
String Split Method
The split() method divides a string into a list of substrings. When called with a space ' ', it splits the string into words.
void main() {
String text = "hello world";
// Split by space
List<String> words = text.split(' ');
print(words); // [hello, world]
// Process each word
for (var word in text.split(' ')) {
print(word); // hello, world
}
}
Map Method
The map() method transforms each element in a collection. It’s perfect for translating each word in a sentence.
void main() {
List<String> words = ['hello', 'world'];
// Transform each word
var translated = words.map((word) => '${word}ay');
print(translated.toList()); // [helloay, worlday]
// Use with split
String text = "hello world";
var result = text.split(' ').map((word) => '${word}ay');
print(result.toList()); // [helloay, worlday]
}
String Join Method
The join() method combines all elements of a list into a single string, with an optional separator between elements.
void main() {
List<String> words = ['helloay', 'worlday'];
// Join with space
String sentence = words.join(' ');
print(sentence); // "helloay worlday"
// Chain with map
String text = "hello world";
String result = text.split(' ').map((word) => '${word}ay').join(' ');
print(result); // "helloay worlday"
}
String StartsWith Method
The startsWith() method checks if a string begins with a specific substring. It’s useful for checking prefixes.
void main() {
String word = "xray";
// Check if starts with prefix
print(word.startsWith('xr')); // true
print(word.startsWith('yt')); // false
print(word.startsWith('a')); // false
// Use in conditionals
if (word.startsWith('xr') || word.startsWith('yt')) {
print("Rule 1 applies");
}
}
String Contains Method
The contains() method checks if a string contains a specific character or substring. It’s useful for checking if a character is a vowel.
void main() {
String vowels = 'aeiou';
// Check if character is a vowel
print(vowels.contains('a')); // true
print(vowels.contains('e')); // true
print(vowels.contains('x')); // false
// Check first character
String word = "apple";
print(vowels.contains(word[0])); // true (a is a vowel)
// Use in conditionals
if (vowels.contains(word[0])) {
print("Starts with vowel");
}
}
String Indexing
Strings can be indexed like arrays to access individual characters. You can check specific positions in a string.
void main() {
String word = "hello";
// Access characters by index
print(word[0]); // 'h'
print(word[1]); // 'e'
print(word[2]); // 'l'
// Check first character
char first = word[0];
print(first); // 'h'
// Use in conditionals
if (word[0] == 'a') {
print("Starts with 'a'");
}
}
String Substring Method
The substring() method extracts a portion of a string. It takes a start index and optionally an end index.
void main() {
String word = "hello";
// Get substring from index to end
String rest = word.substring(2);
print(rest); // "llo"
// Get substring with start and end
String middle = word.substring(1, 4);
print(middle); // "ell"
// Split word into parts
int splitIndex = 2;
String part1 = word.substring(0, splitIndex); // "he"
String part2 = word.substring(splitIndex); // "llo"
String result = part2 + part1;
print(result); // "llohe"
}
While Loops
While loops repeatedly execute a block of code as long as a condition is true. They’re perfect for finding positions in strings.
void main() {
String word = "hello";
int i = 0;
// Iterate through characters
while (i < word.length) {
print(word[i]); // h, e, l, l, o
i++;
}
// Find first vowel
int index = 0;
while (index < word.length && !'aeiou'.contains(word[index])) {
index++;
}
print(index); // 1 (first vowel 'e' at index 1)
}
Helper Methods
Helper methods break down complex logic into smaller, reusable functions. They improve code readability and maintainability.
String translate(String text) {
return text.split(' ').map(_translateWord).join(' ');
}
// Helper method: translate a single word
String _translateWord(String word) {
// Translation logic...
}
// Helper method: check if starts with vowel
bool _startsWithVowel(String word) {
return 'aeiou'.contains(word[0]);
}
Conditional Logic
Conditional statements allow you to execute different code based on conditions. This is essential for handling different translation rules.
void main() {
String word = "apple";
// Check different conditions
if (_startsWithVowel(word)) {
// Rule 1: starts with vowel
print('${word}ay');
} else if (word.startsWith('xr')) {
// Rule 1: starts with "xr"
print('${word}ay');
} else {
// Rule 2: starts with consonants
// Move consonants to end...
}
}
String Interpolation
String interpolation allows you to embed expressions and variables directly within strings using ${expression} or $variable.
void main() {
String word = "hello";
String suffix = "ay";
// Build string with interpolation
String result = '${word}${suffix}';
print(result); // "helloay"
// Combine parts
String part1 = "ell";
String part2 = "oh";
String combined = '${part1}${part2}ay';
print(combined); // "ellohay"
}
Increment Operator
The increment operator (++) increases a variable by 1. It’s commonly used in loops to move through string indices.
void main() {
int i = 0;
// Increment
i++;
print(i); // 1
// Use in loops
String word = "hello";
int index = 0;
while (index < word.length) {
print(word[index]);
index++; // Move to next character
}
}
Introduction
Your parents have challenged you and your sibling to a game of two-on-two basketball. Confident they’ll win, they let you score the first couple of points, but then start taking over the game. Needing a little boost, you start speaking in Pig Latin, which is a made-up children’s language that’s difficult for non-children to understand. This will give you the edge to prevail over your parents!
Instructions
Your task is to translate text from English to Pig Latin. The translation is defined using four rules, which look at the pattern of vowels and consonants at the beginning of a word. These rules look at each word’s use of vowels and consonants:
- vowels: the letters a, e, i, o, and u
- consonants: the other 21 letters of the English alphabet
Rule 1
If a word begins with a vowel, or starts with “xr” or “yt”, add an “ay” sound to the end of the word.
For example:
- “apple” → “appleay” (starts with vowel)
- “xray” → “xrayay” (starts with “xr”)
- “yttria” → “yttriaay” (starts with “yt”)
Rule 2
If a word begins with one or more consonants, first move those consonants to the end of the word and then add an “ay” sound to the end of the word.
For example:
- “pig” → “igp” → “igpay” (starts with single consonant)
- “chair” → “airch” → “airchay” (starts with multiple consonants)
- “thrush” → “ushthr” → “ushthray” (starts with multiple consonants)
Rule 3
If a word starts with zero or more consonants followed by “qu”, first move those consonants (if any) and the “qu” part to the end of the word, and then add an “ay” sound to the end of the word.
For example:
- “quick” → “ickqu” → “ickquay” (starts with “qu”, no preceding consonants)
- “square” → “aresqu” → “aresquay” (starts with one consonant followed by “qu”)
Rule 4
If a word starts with one or more consonants followed by “y”, first move the consonants preceding the “y” to the end of the word, and then add an “ay” sound to the end of the word.
Some examples:
- “my” → “ym” → “ymay” (starts with single consonant followed by “y”)
- “rhythm” → “ythmrh” → “ythmrhay” (starts with multiple consonants followed by “y”)
How can we translate to Pig Latin?
To translate text to Pig Latin:
- Split into words: Divide the text by spaces
- Translate each word: Apply the appropriate rule to each word
- Join results: Combine translated words back into a sentence
For each word:
- Rule 1: If starts with vowel, “xr”, or “yt” → add “ay” to end
- Rule 2-4: Find where consonants end (first vowel, or special cases)
- Rule 3: “qu” is treated as a unit (move it together)
- Rule 4: “y” after consonants acts as a vowel
- Move consonant cluster to end and add “ay”
The key insight is finding the split point where consonants end and the vowel part begins, handling special cases like “qu” and “y” after consonants.
Solution
String translate(String text) {
return text.split(' ').map(_translateWord).join(' ');
}
String _translateWord(String word) {
// Rule 1: Vowel at start, or "xr"/"yt" prefix
if (_isRule1(word)) {
return '${word}ay';
}
// Rules 2, 3, 4: Move consonant cluster to end
final splitIndex = _findSplitIndex(word);
return '${word.substring(splitIndex)}${word.substring(0, splitIndex)}ay';
}
bool _isRule1(String word) {
return _startsWithVowel(word) ||
word.startsWith('xr') ||
word.startsWith('yt');
}
bool _startsWithVowel(String word) {
return 'aeiou'.contains(word[0]);
}
int _findSplitIndex(String word) {
var i = 0;
while (i < word.length) {
final char = word[i];
// Found a vowel (but not 'y' at the beginning)
if ('aeiou'.contains(char)) {
return i;
}
// Rule 4: 'y' after consonants acts as a vowel
if (char == 'y' && i > 0) {
return i;
}
// Rule 3: Handle "qu" as a unit
if (i < word.length - 1 && word.substring(i, i + 2) == 'qu') {
return i + 2;
}
i++;
}
return i;
}
Let’s break down the solution:
-
String translate(String text)- Main method that translates a sentence:text.split(' '): Splits the text into individual words.map(_translateWord): Translates each word using the helper method.join(' '): Joins the translated words back into a sentence with spaces- Returns the complete translated sentence
-
String _translateWord(String word)- Translates a single word:if (_isRule1(word)): Checks if Rule 1 applies (starts with vowel, “xr”, or “yt”)return '${word}ay': If Rule 1, simply add “ay” to the endfinal splitIndex = _findSplitIndex(word): Otherwise, find where to split the wordword.substring(splitIndex): Gets the part from split point to end (vowel part)word.substring(0, splitIndex): Gets the part from start to split point (consonants)return '${word.substring(splitIndex)}${word.substring(0, splitIndex)}ay': Moves consonants to end and adds “ay”
-
bool _isRule1(String word)- Checks if Rule 1 applies:_startsWithVowel(word): Checks if word starts with a vowelword.startsWith('xr'): Checks if word starts with “xr”word.startsWith('yt'): Checks if word starts with “yt”- Returns
trueif any condition is true (uses OR operator||)
-
bool _startsWithVowel(String word)- Checks if word starts with a vowel:'aeiou'.contains(word[0]): Checks if the first character is in the vowel string- Returns
trueif first character is a, e, i, o, or u
-
int _findSplitIndex(String word)- Finds where to split the word:var i = 0: Start at the beginning of the wordwhile (i < word.length): Loop through each character
-
Vowel check:
if ('aeiou'.contains(char)):- If current character is a vowel, return its index
- This handles Rule 2 (consonants followed by vowel)
-
Rule 4 check:
if (char == 'y' && i > 0):char == 'y': Current character is ‘y’i > 0: ‘y’ is not at the beginning (after consonants)- Returns index of ‘y’ (treats ‘y’ as vowel when after consonants)
-
Rule 3 check:
if (i < word.length - 1 && word.substring(i, i + 2) == 'qu'):i < word.length - 1: Ensure we can check two charactersword.substring(i, i + 2) == 'qu': Check if current position starts “qu”return i + 2: Return index after “qu” (treats “qu” as a unit)
-
i++- Move to next character:- Increments index to continue searching
-
return i- Fallback:- Returns word length if no vowel found (shouldn’t happen in valid words)
The solution efficiently translates text to Pig Latin by splitting words, identifying the appropriate rule, and moving consonant clusters to the end while handling special cases like “qu” and “y” after consonants.
A video tutorial for this exercise is coming soon! In the meantime, check out my YouTube channel for more Dart and Flutter tutorials. 😉
Visit My YouTube Channel