弊社のメイン言語がElixirになったので、Elixir習得時に書いたFizzBuzzをご紹介します。Elixir初心者の頃に書いたので所々おかしい気もするのですが、そのまま掲載します。
fizzBuzz.exs
defmodule FizzBuzz do
def fizzBuzz(num), do: _notFB(_fizz(oneDigit(Integer.to_charlist(num))) <> _buzz(_getLastDigit(Integer.to_charlist(num))) , num)
def sumDigit([head | []]), do: head - 48
def sumDigit([head | tail]), do: head - 48 + sumDigit(tail)
def oneDigit([head | []]), do: head - 48
def oneDigit(list), do: oneDigit(Integer.to_charlist(sumDigit(list)))
def _fizz(3), do: "Fizz"
def _fizz(6), do: "Fizz"
def _fizz(9), do: "Fizz"
def _fizz(_), do: ""
def _getLastDigit([head | []]), do: head - 48
def _getLastDigit([_ | tail]), do: _getLastDigit(tail)
def _buzz(5), do: "buzz"
def _buzz(0), do: "buzz"
def _buzz(_), do: ""
def _notFB("", num), do: Integer.to_charlist(num)
def _notFB(some, _), do: some
end
Enum.map(1..100, fn(x) -> IO.puts FizzBuzz.fizzBuzz(x) end)
解説
module FizzBuzz
FizzBuzzというモジュールを定義しています。
fizzBuzz
数字を入れるとFizzBuzzしてくれる関数です。下で定義した関数のまとめです。
今回は、
* 3の倍数なら"Fizz"を返し、違ったら空文字列を返す関数
* 5の倍数なら"Buzz"を返し、違ったら空文字列を返す関数
の二つを定義し、その関数の結果に対し文字列を結合するというアプローチをとっています。
sumDigit, oneDigit, _fizz
今回のFizzBuzzでは、3の倍数は各桁の和を取ると3の倍数になるという性質を再帰的に利用しています。sumDigitとoneDigitで最後の一桁になるまで各桁の和を取り続け、_fizzで判定しています。
_getLastDigit, _buzz
5の倍数の判定は簡単で、末尾が5か0なら5の倍数です。
_notFB
二つの引数をとり、一つ目の引数が空文字列なら2つ目の引数をcharに変換したものを返し、それ以外の場合は一つ目の引数を返します。
enumの行
関数を実行してIO.putsしています。
まとめ
FizzBuzzは非常に奥が深いので、ぜひみなさんやってみましょう。