Avatar of PatrickMcSweeny
0
0
Genius
0
0

PatrickMcSweeny's solution

to Pig Latin in the Ruby Track

0
0
Genius
0
0
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.


For installation and learning resources, refer to the Ruby resources page.

For running the tests provided, you will need the Minitest gem. Open a terminal window and run the following command to install minitest:

gem install minitest

If you would like color output, you can require 'minitest/pride' in the test file, or note the alternative instruction, below, for running the test file.

Run the tests from the exercise directory using the following command:

ruby pig_latin_test.rb

To include color from the command line:

ruby -r minitest/pride pig_latin_test.rb

Source

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

Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.

pig_latin_test.rb

require 'minitest/autorun'
require_relative 'pig_latin'

# Common test data version: 1.2.0 d77de78
class PigLatinTest < Minitest::Test
  def test_word_beginning_with_a
    # skip
    assert_equal "appleay", PigLatin.translate("apple")
  end

  def test_word_beginning_with_e
    skip
    assert_equal "earay", PigLatin.translate("ear")
  end

  def test_word_beginning_with_i
    skip
    assert_equal "iglooay", PigLatin.translate("igloo")
  end

  def test_word_beginning_with_o
    skip
    assert_equal "objectay", PigLatin.translate("object")
  end

  def test_word_beginning_with_u
    skip
    assert_equal "underay", PigLatin.translate("under")
  end

  def test_word_beginning_with_a_vowel_and_followed_by_a_qu
    skip
    assert_equal "equalay", PigLatin.translate("equal")
  end

  def test_word_beginning_with_p
    skip
    assert_equal "igpay", PigLatin.translate("pig")
  end

  def test_word_beginning_with_k
    skip
    assert_equal "oalakay", PigLatin.translate("koala")
  end

  def test_word_beginning_with_x
    skip
    assert_equal "enonxay", PigLatin.translate("xenon")
  end

  def test_word_beginning_with_q_without_a_following_u
    skip
    assert_equal "atqay", PigLatin.translate("qat")
  end

  def test_word_beginning_with_ch
    skip
    assert_equal "airchay", PigLatin.translate("chair")
  end

  def test_word_beginning_with_qu
    skip
    assert_equal "eenquay", PigLatin.translate("queen")
  end

  def test_word_beginning_with_qu_and_a_preceding_consonant
    skip
    assert_equal "aresquay", PigLatin.translate("square")
  end

  def test_word_beginning_with_th
    skip
    assert_equal "erapythay", PigLatin.translate("therapy")
  end

  def test_word_beginning_with_thr
    skip
    assert_equal "ushthray", PigLatin.translate("thrush")
  end

  def test_word_beginning_with_sch
    skip
    assert_equal "oolschay", PigLatin.translate("school")
  end

  def test_word_beginning_with_yt
    skip
    assert_equal "yttriaay", PigLatin.translate("yttria")
  end

  def test_word_beginning_with_xr
    skip
    assert_equal "xrayay", PigLatin.translate("xray")
  end

  def test_y_is_treated_like_a_consonant_at_the_beginning_of_a_word
    skip
    assert_equal "ellowyay", PigLatin.translate("yellow")
  end

  def test_y_is_treated_like_a_vowel_at_the_end_of_a_consonant_cluster
    skip
    assert_equal "ythmrhay", PigLatin.translate("rhythm")
  end

  def test_y_as_second_letter_in_two_letter_word
    skip
    assert_equal "ymay", PigLatin.translate("my")
  end

  def test_a_whole_phrase
    skip
    assert_equal "ickquay astfay unray", PigLatin.translate("quick fast run")
  end
end
class PigLatin
  def self.translate(input)
    new(input).translate
  end

  def initialize(input)
    @words = input.split ' '
  end

  def translate
    words.map { |word| translate_word(word) }.join ' '
  end

  private

  attr_reader :words

  def translate_word(word)
    scan_word(word) + 'ay'
  end

  def scan_word(word)
    case word
    when vowel_sound
      word
    when consonant_followed_by_qu
      beginning = word.scan(consonant_followed_by_qu).first
      word.gsub!(consonant_followed_by_qu, '')
      word + beginning
    when consonant_cluster_y
      beginning = word.scan(/^[^aeiouy]*/).first
      word.gsub!(/^[^aeiouy]*/, '')
      word + beginning
    when consonant_sound
      first = word.scan(/^#{consonant}+/).first
      word.gsub(/^#{consonant}+/, '') + first
    end
  end

  def consonant_sound
    /^#{consonant}/
  end

  def consonant
    '[^aeiou]'
  end

  def consonant_followed_by_qu
    /^[^aeiou]*qu/
  end

  def vowel_sound
    /^[aeiou]|^xr|^yt/
  end

  def consonant_cluster_y
    /^[^aeiou]+y/
  end
end

What can you learn from this solution?

A huge amount can be learnt 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 I could read more about to develop my understanding?