LoginSignup
2
1

More than 5 years have passed since last update.

Elixirで縛りFizzBuzz! 条件分岐、剰余、三進数、五進数を使わず、def文だけでFizzBuzzする

Posted at

弊社のメイン言語が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は非常に奥が深いので、ぜひみなさんやってみましょう。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1