🎉 Exercism Research is now launched. Help Exercism, help science and have some fun at research.exercism.io 🎉
Avatar of davidfrogley

davidfrogley's solution

to Pig Latin in the C# Track

Published at Aug 31 2020 · 0 comments
Instructions
Test suite
Solution

Implement a program that translates from English to Pig Latin.

Pig Latin is a made-up children's language that's intended to be confusing. It obeys a few simple rules (below), but when it's spoken quickly it's really difficult for non-children (and non-native speakers) to understand.

  • Rule 1: If a word begins with a vowel sound, add an "ay" sound to the end of the word. Please note that "xr" and "yt" at the beginning of a word make vowel sounds (e.g. "xray" -> "xrayay", "yttria" -> "yttriaay").
  • Rule 2: If a word begins with a consonant sound, move it to the end of the word and then add an "ay" sound to the end of the word. Consonant sounds can be made up of multiple consonants, a.k.a. a consonant cluster (e.g. "chair" -> "airchay").
  • Rule 3: If a word starts with a consonant sound followed by "qu", move it to the end of the word, and then add an "ay" sound to the end of the word (e.g. "square" -> "aresquay").
  • Rule 4: If a word contains a "y" after a consonant cluster or as the second letter in a two letter word it makes a vowel sound (e.g. "rhythm" -> "ythmrhay", "my" -> "ymay").

There are a few more rules for edge cases, and there are regional variants too.

See http://en.wikipedia.org/wiki/Pig_latin for more details.

Running the tests

To run the tests, run the command dotnet test from within the exercise directory.

Initially, only the first test will be enabled. This is to encourage you to solve the exercise one step at a time. Once you get the first test passing, remove the Skip property from the next test and work on getting that test passing. Once none of the tests are skipped and they are all passing, you can submit your solution using exercism submit PigLatin.cs

Further information

For more detailed information about the C# track, including how to get help if you're having trouble, please visit the exercism.io C# language page.

Source

The Pig Latin exercise at Test First Teaching by Ultrasaurus https://github.com/ultrasaurus/test-first-teaching/blob/master/learn_ruby/pig_latin/

PigLatinTests.cs

// This file was auto-generated based on version 1.2.0 of the canonical data.

using Xunit;

public class PigLatinTests
{
    [Fact]
    public void Word_beginning_with_a()
    {
        Assert.Equal("appleay", PigLatin.Translate("apple"));
    }

    [Fact(Skip = "Remove this Skip property to run this test")]
    public void Word_beginning_with_e()
    {
        Assert.Equal("earay", PigLatin.Translate("ear"));
    }

    [Fact(Skip = "Remove this Skip property to run this test")]
    public void Word_beginning_with_i()
    {
        Assert.Equal("iglooay", PigLatin.Translate("igloo"));
    }

    [Fact(Skip = "Remove this Skip property to run this test")]
    public void Word_beginning_with_o()
    {
        Assert.Equal("objectay", PigLatin.Translate("object"));
    }

    [Fact(Skip = "Remove this Skip property to run this test")]
    public void Word_beginning_with_u()
    {
        Assert.Equal("underay", PigLatin.Translate("under"));
    }

    [Fact(Skip = "Remove this Skip property to run this test")]
    public void Word_beginning_with_a_vowel_and_followed_by_a_qu()
    {
        Assert.Equal("equalay", PigLatin.Translate("equal"));
    }

    [Fact(Skip = "Remove this Skip property to run this test")]
    public void Word_beginning_with_p()
    {
        Assert.Equal("igpay", PigLatin.Translate("pig"));
    }

    [Fact(Skip = "Remove this Skip property to run this test")]
    public void Word_beginning_with_k()
    {
        Assert.Equal("oalakay", PigLatin.Translate("koala"));
    }

    [Fact(Skip = "Remove this Skip property to run this test")]
    public void Word_beginning_with_x()
    {
        Assert.Equal("enonxay", PigLatin.Translate("xenon"));
    }

    [Fact(Skip = "Remove this Skip property to run this test")]
    public void Word_beginning_with_q_without_a_following_u()
    {
        Assert.Equal("atqay", PigLatin.Translate("qat"));
    }

    [Fact(Skip = "Remove this Skip property to run this test")]
    public void Word_beginning_with_ch()
    {
        Assert.Equal("airchay", PigLatin.Translate("chair"));
    }

    [Fact(Skip = "Remove this Skip property to run this test")]
    public void Word_beginning_with_qu()
    {
        Assert.Equal("eenquay", PigLatin.Translate("queen"));
    }

    [Fact(Skip = "Remove this Skip property to run this test")]
    public void Word_beginning_with_qu_and_a_preceding_consonant()
    {
        Assert.Equal("aresquay", PigLatin.Translate("square"));
    }

    [Fact(Skip = "Remove this Skip property to run this test")]
    public void Word_beginning_with_th()
    {
        Assert.Equal("erapythay", PigLatin.Translate("therapy"));
    }

    [Fact(Skip = "Remove this Skip property to run this test")]
    public void Word_beginning_with_thr()
    {
        Assert.Equal("ushthray", PigLatin.Translate("thrush"));
    }

    [Fact(Skip = "Remove this Skip property to run this test")]
    public void Word_beginning_with_sch()
    {
        Assert.Equal("oolschay", PigLatin.Translate("school"));
    }

    [Fact(Skip = "Remove this Skip property to run this test")]
    public void Word_beginning_with_yt()
    {
        Assert.Equal("yttriaay", PigLatin.Translate("yttria"));
    }

    [Fact(Skip = "Remove this Skip property to run this test")]
    public void Word_beginning_with_xr()
    {
        Assert.Equal("xrayay", PigLatin.Translate("xray"));
    }

    [Fact(Skip = "Remove this Skip property to run this test")]
    public void Y_is_treated_like_a_consonant_at_the_beginning_of_a_word()
    {
        Assert.Equal("ellowyay", PigLatin.Translate("yellow"));
    }

    [Fact(Skip = "Remove this Skip property to run this test")]
    public void Y_is_treated_like_a_vowel_at_the_end_of_a_consonant_cluster()
    {
        Assert.Equal("ythmrhay", PigLatin.Translate("rhythm"));
    }

    [Fact(Skip = "Remove this Skip property to run this test")]
    public void Y_as_second_letter_in_two_letter_word()
    {
        Assert.Equal("ymay", PigLatin.Translate("my"));
    }

    [Fact(Skip = "Remove this Skip property to run this test")]
    public void A_whole_phrase()
    {
        Assert.Equal("ickquay astfay unray", PigLatin.Translate("quick fast run"));
    }
}
using System;
using System.Linq;


public static class PigLatin
{
	private static readonly char[] Vowels = new[] { 'a', 'e', 'i', 'o', 'u' };


	public static string Translate(string phrase)
	{
		return string.Join(" ", phrase.Split(" ")
			.Select(word => TranslateWord(word.ToLower())));
	}


	private static string TranslateWord(string word)
	{
		// Rule 1: If a word begins with a vowel sound, add an "ay" sound to the end of the word.
		if ((Array.IndexOf(Vowels, word[0]) != -1) || word.StartsWith("xr") || word.StartsWith("yt"))
		{
			return word + "ay";
		}

		// Rule 2: If a word begins with a consonant sound, move it to the end of the word and then add an "ay" sound to the end of the word.
		var firstVowel = word.IndexOfAny(Vowels);
		var firstY = word.IndexOf('y');

		// Rule 4: If a word contains a "y" after a consonant cluster or as the second letter in a two-letter word, it makes a vowel sound.
		if ((firstY > 0) && ((firstVowel == -1) || (firstY < firstVowel)))
		{
			firstVowel = firstY;
		}

		// Rule 3: If a word starts with a consonant sound followed by "qu", move it to the end of the word, and then add an "ay" sound to the end of the word.
		if ((word[firstVowel] == 'u') && (word[firstVowel - 1] == 'q'))
		{
			++firstVowel;
		}

		return word.Substring(firstVowel) + word.Substring(0, firstVowel) + "ay";
	}
}

Community comments

Find this solution interesting? Ask the author a question to learn more.

What can you learn from this solution?

A huge amount can be learned from reading other people’s code. This is why we wanted to give exercism users the option of making their solutions public.

Here are some questions to help you reflect on this solution and learn the most from it.

  • What compromises have been made?
  • Are there new concepts here that you could read more about to improve your understanding?