Igpay Igpay Atinlay

The other day I watched an interesting episode of Teen Titans Go with my kids. What caught our attention is the song that was part of the episode. You can listen to it here.

Despite the song being fun for my kids to listen to, my daughter asked me if those words made any sense at all. Do they? 🙂

At first I thought it was a simple rotation system. For example, “test” would turn to “estt”, and “scheme” would turn to “chemes”. This is what I told my daughter without any further analysis and we had fun playing with the words.

But then after a while we heard the song again and it seems our system isn’t what was used. Next thinking was, they would rotate the words, and append “ay” at the end of them. So I found the transcript and I noted this works, but you need to keep rotating until you reach a vowel. That’s it! I quickly sat and wrote an encoder in Scheme:

(define (word-to-piglatin str)
  (letrec [(vowels '(#\a #\e #\i #\o #\u))
           (l (string->list str))]
    (cond ((> (length (set-intersect vowels l)) 0)
           (if (member (car l) vowels)
               (list->string (append l '(#\a #\y)))
               (word-to-piglatin (list->string (append (cdr l) (list (car l)))))))
          (else (error "no vowels")))))

Now, just run it:

> (let ([song "pig pig latin is the dopest its real simple i will explain pig pig latin is the dopest say ay always at ends of words pig pig latin is the dopest"])
    (string-join (map word-to-piglatin (string-split song " ")) " "))
"igpay igpay atinlay isay ethay opestday itsay ealray implesay iay illway explainay igpay igpay atinlay isay ethay opestday aysay ayay alwaysay atay endsay ofay ordsway igpay igpay atinlay isay ethay opestday"

Ahh, close, but not really. If you look at the song lyrics, some words do not match. Specifically “isway” vs “isay”. So I thought maybe for some ending letters we append “ay” and for others we append “way”.

Constructing a table was the next step:

Ends in letter | Append
       a       | way
       b       | ay
       c       | ay
       d       | ay|way
       e       | way
       f       | ay|way
       g       |
       h       | ay|way
       i       | way
       j       |
       k       | way
       l       | ay|way
       m       | ay|way
       n       | ay|way
       o       |
       p       | ay|way
       q       |
       r       | ay
       s       | ay|way
       t       | ay|way
       u       |
       v       | ay
       w       | ay
       x       |
       y       | ay|way
       z       |

Nope, for some words it’s “ay”, for some it’s “way”, and for some it’s both. Also, for “on” it’s sometimes “onway” and sometimes “onay”. So it’s pretty random, but was still fun to look into! 🙂

EDIT: Thanks to my coworker Bartosz Budzanowski who told me that Pig Latin is really a thing! The rules are clearly stated on its Wikipedia page. Still, reverse engineering it was fun 🙂

Code updated:

(define (word-to-piglatin str [init #t])
  (letrec [(vowels '(#\a #\e #\i #\o #\u))
           (l (string->list str))]
    (cond ((> (length (set-intersect vowels l)) 0)
           (if (member (car l) vowels)
               (list->string (append l (if init '(#\w #\a #\y) '(#\a #\y))))
               (word-to-piglatin (list->string (append (cdr l) (list (car l)))) #f)))
          (else (error "no vowels")))))

Bonus: Haskell code

WordToPiglatin :: String -> String
WordToPiglatin "" = ""
WordToPiglatin s
    | isVowel (head s) = s ++ "way"
    | any isVowel s    = rotateUntil (isVowel . head) s ++ "ay"
    | otherwise        = s
    where
    isVowel c = c `elem` "aeiouAEIOU"
    rotateUntil _ [] = []
    rotateUntil p s = let res = rotate s in if p res then res else rotateUntil p res
    rotate (x:xs) = xs ++ [x]

One thought on “Igpay Igpay Atinlay

Leave a comment