호두나무 공방/Exercism in Elixir

Pig Latin - Exercism in Elixir

2022. 6. 2. 22:49

문제 보기

영단어를 pig latin(알파벳의 순서를 바꾸는 말장난)으로 바꾸는 문제였다. 아무래도 영어가 모국어가 아니다보니 익숙한 변환 룰이 아니어서 테스트 케이스를 맞추는 데에 제법 애를 먹었다. 바이너리 패턴 매칭을 쓸 수도 있을 것 같은데, 잘 적용하는 방법이 떠오르지 않아 일단 그나마 간단한 방법인 정규식으로 해결했다.

defmodule PigLatin do
  @doc """
  Given a `phrase`, translate it a word at a time to Pig Latin.
  """
  @spec translate(phrase :: String.t()) :: String.t()
  def translate(phrase) do
    phrase
    |> String.split(" ")
    |> Enum.map(&translate_word/1)
    |> Enum.join(" ")
  end

  defp translate_word(word) do
    cond do
      String.match?(word, ~r/^(([aeiou])+)(.*)$/) ->
        word <> "ay"
      String.match?(word, ~r/^([xy])([^aeiou]+)(.*)$/) ->
        String.replace(word, ~r/^([xy])([^aeiou]+)(.*)$/, "\\g{1}\\g{2}\\g{3}ay")
      String.match?(word, ~r/^([^aeiou]*)(qu)(.*)$/) ->
        String.replace(word, ~r/^([^aeiou]*)(qu)(.*)$/, "\\g{3}\\g{1}\\g{2}ay")
      String.match?(word, ~r/^([^aeiou]+)(y)(.*)$/) ->
        String.replace(word, ~r/^([^aeiou]+)(y)(.*)$/, "\\g{2}\\g{3}\\g{1}ay")
      String.match?(word, ~r/^([^aeiou]+)(.*)$/) ->
        String.replace(word, ~r/^([^aeiou]+)(.*)$/, "\\g{2}\\g{1}ay")
    end
  end
end