DEV Community

dev.to staff
dev.to staff

Posted on

Daily Challenge #22 - Simple Pig Latin

The goal of today's challenge is to translate English into Pig Latin. This challenge comes from user2505876 on CodeWars.

Write a function that moves the first letter of each word to the end of the word, then add "ay". Leave punctuation untouched.

Examples:
pig_it('Pig latin is cool') # igPay atinlay siay oolcay
pig_it('Hello world !') # elloHay orldway !

This one is somewhat tricky. I bet it would be even harder to turn Pig Latin back to English, I'd love to see someone try it~!

Oodgay ucklay, appyhay odingcay!


Thank you to CodeWars, who has licensed redistribution of this challenge under the 2-Clause BSD License!

Want to propose a challenge for a future post? Email yo+challenge@dev.to with your suggestions!

Top comments (18)

Collapse
 
alvaromontoro profile image
Alvaro Montoro

CSS (kind of)

Separate the words in <span>s, and add the class "piglatin" to the container.

.piglatin span {
  display: inline-block;
  position: relative;
  margin-right: 1em;
}

.piglatin span::first-letter {
  float: right;
}

.piglatin span::after {
  content: "ay";
  position: absolute;
  left: 100%;
}

The idea is based on floating the first letter to the right using the pseudo-class :first-letter, and then adding "ay" using the pseudo-element ::after... although it doesn't work well with punctuation :-/

You can see a demo running on CodePen:

Collapse
 
alvaromontoro profile image
Alvaro Montoro

Screen readers still read the sentences right, even when visually they are in pig latin.

Collapse
 
coreyja profile image
Corey Alexander

So happy to see another CSS solution! It's been awhile lol

Hell of a job!

Collapse
 
alvaromontoro profile image
Alvaro Montoro

Yes. The last ones have been impossible. But 4-5 out of 22 is not that bad :P

Collapse
 
florinpop17 profile image
Florin Pop

Oh, this is nice! ☺️

Collapse
 
ynndvn profile image
La blatte • Edited

Here goes a JavaScript oneliner

const pigIt = (s) => s.split(' ').map(e=>e.match(/\w/)?`${e.slice(1)}${e[0]}ay`:e).join(' ')
Enter fullscreen mode Exit fullscreen mode
pigIt('Pig Latin is cool');
"igPay atinLay siay oolcay"

pigIt('Hello world !');
"elloHay orldway !"
Enter fullscreen mode Exit fullscreen mode

And just for fun, an unPigIt oneliner too!

const unPigIt = (s) => s.split(' ').map(e=>e.match(/\w/)?e[e.length-3]+e.slice(0,-3):e).join(' ')

Enter fullscreen mode Exit fullscreen mode
unPigIt('igPay atinLay siay oolcay');
"Pig Latin is cool"

unPigIt('elloHay orldway !');
"Hello world !"
Enter fullscreen mode Exit fullscreen mode
Collapse
 
petecapecod profile image
Peter Cruckshank

Nailed it 👌🔥🔥

Collapse
 
yzhernand profile image
Yozen Hernandez

Perl one-liner as well

say join(" ", map { s/(\w)(\w+)/\2\1ay/r } split /\s/, "Pig latin is cool")

#igPay atinlay siay oolcay

This one handles leaving punctuation alone, so this would work as well:

say join(" ", map { s/(\w)(\w+)/\2\1ay/r } split /\s/, '"Pig" latin is cool')

#"igPay" atinlay siay oolcay
Collapse
 
choroba profile image
E. Choroba

No need to split and join:

say '"Pig" latin is cool' =~ s/(\w)(\w+)/$2$1ay/gr;
Collapse
 
yzhernand profile image
Yozen Hernandez

Of course. Thanks!

Collapse
 
aadibajpai profile image
Aadi Bajpai • Edited

python one liner ftw.

print(*map(lambda x: f'{x[1:]+x[0]}ay' if x.isalpha() else x, input().split()))
>>> print(*map(lambda x: f'{x[1:]+x[0]}ay' if x.isalpha() else x, input().split()))
Pig latin is cool
igPay atinlay siay oolcay
Collapse
 
kaspermeyer profile image
Kasper Meyer • Edited

Ruby 2.6

require "minitest/autorun"

class PigLatinTranslator
  LATINATOR = -> (word) { word =~ /\w/ ? "#{word[1..-1]}#{word[0]}ay" : word }

  def self.translate sentence
    sentence.split(' ').map(&LATINATOR).join(' ')
  end
end

class PigLatinTranslatorTest < MiniTest::Test
  def test_sentence_without_punctuation
    translated_sentence = PigLatinTranslator.translate("Pig latin is cool")

    assert_equal "igPay atinlay siay oolcay", translated_sentence
  end

  def test_sentence_with_punctuation
    translated_sentence = PigLatinTranslator.translate("Hello world !")

    assert_equal "elloHay orldway !", translated_sentence
  end
end
Collapse
 
jasman7799 profile image
Jarod Smith • Edited
const vowels = ['a','i','e','o','u'];
// checkVowels :: String -> Bool
const checkVowel = str => vowels.includes(str.charAt(0))
// translate:: String -> String
const translate = str => checkVowel(str)? str + 'way ' : str.substring(1,str.length)+ str.charAt(0) + 'ay'
// pigLatin :: String -> [String] -> String  
const pigLatin = str => str.split(' ').map(word => translate(word)).join(" ")
Collapse
 
coreyja profile image
Corey Alexander

Rust Solution!

I paid specific attention to the punctuation rule, and made sure to get that right!

I also wasn't satisfied with just the example punctuation because nobody spaces out their punctuation like that ! See doesn't that look weird ?
Also the spec doesn't mention at all with how to treat words with punctuation IN them! So I made my own spec here and decided to split the words on any punctuation, and treat each side as it own word. Proper pig latin? Maybe not! But it's doing what I intended!

fn pigify_word(word: &str) -> String {
    println!("{}", word);
    if word.chars().all(|x| x.is_alphanumeric()) {
        let mut chars = word.chars();
        let first_letter = chars.next().unwrap();
        let rest_of_letters: String = chars.collect();

        format!("{}{}ay", rest_of_letters, first_letter)
    } else if word.chars().all(|x| !x.is_alphanumeric()) {
        word.to_string()
    } else {
        let symbol_index = word.find(|c: char| !c.is_alphanumeric()).unwrap();
        let alphanumeric_index = word.find(|c: char| c.is_alphanumeric()).unwrap();

        let index = symbol_index.max(alphanumeric_index);

        [word[0..index].to_string(), word[index..].to_string()]
            .iter()
            .map(|x| pigify_word(x))
            .collect()
    }
}

pub fn pig_it(english_input: &str) -> String {
    english_input
        .split(" ")
        .map(pigify_word)
        .collect::<Vec<_>>()
        .join(" ")
}

#[cfg(test)]
mod tests {
    use crate::*;

    #[test]
    fn it_works_without_punctuation() {
        assert_eq!(
            pig_it("Pig latin is cool"),
            "igPay atinlay siay oolcay".to_string()
        );
    }

    #[test]
    fn it_works_with_spaced_out_punctuation() {
        assert_eq!(pig_it("Hello world !"), "elloHay orldway !".to_string());
    }

    #[test]
    fn it_works_with_word_ending_punctuation() {
        assert_eq!(
            pig_it("Hello world! How is it going today?"),
            "elloHay orldway! owHay siay tiay oinggay odaytay?".to_string()
        );
    }

    #[test]
    fn it_works_with_word_mid_punctuation() {
        assert_eq!(
            pig_it("Hello world! How's it going today?"),
            "elloHay orldway! owHay'say tiay oinggay odaytay?".to_string()
        );
    }
}

Collapse
 
peter279k profile image
peter279k

Here is the simple solution with Python:

def pig_it(text):
    answer = ""
    pig_prefix = "ay"

    text_list = text.split(' ')

    for text in text_list:
        first_text = text[0]

        start_index = 1
        if len(text) == 0:
            start_index = 0

        if first_text == "?" or first_text == "!" or first_text == "," or first_text == ".":
            answer += text
        else:
            answer += text[start_index:] + first_text + pig_prefix + " " 

    if answer[-1] == " ":
        return answer[0:-1]

    return answer
Collapse
 
brightone profile image
Oleksii Filonenko • Edited

Elixir:

defmodule PigLatin do
  def pig_it(input) do
    input
    |> String.split()
    |> Enum.map(&latinate/1)
    |> Enum.join(" ")
  end

  defp latinate(<<first_letter::binary-size(1), rest::binary>>),
    do: rest <> first_letter <> "ay"
end
Collapse
 
devparkk profile image
Dev Prakash • Edited
Collapse
 
barycenter profile image
Don Sudduth

Your pig latin rules are incorrect in the Examples. Words beginning with vowels do not move the first letter and traditionally end in 'way'. So pig_it('Pig latin is cool') should be # igPay atinlay isway oolcay