LoginSignup
1
0

More than 5 years have passed since last update.

16個のワンライナーdef文で構成された縛りFizzBuzz。if, 剰余禁止

Posted at

何日めか忘れたけどFizzBuzzアドベントカレンダーです。

今回のコンセプト

  • if文を使わない
  • 剰余を使わない
  • 実行文とモジュール定義文以外全部ワンライナーのdef文
  • その他無駄なこだわり

ソースコード

fizz_buzz.ex
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)

解説

Elixirで書きました。If文を使わない、の部分はパターンマッチで対処しています。

上から読んでいきます。

FizzBuzz本体

   def fizzBuzz(num), do: _notFB(_fizz(oneDigit(Integer.to_charlist(num))) <> _buzz(_getLastDigit(Integer.to_charlist(num))) , num)

他で定義した関数をつなげて実行するだけです。

Fizz

  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: ""

今回は剰余を使わない、という条件があるため、各桁の和が3の倍数であれば3の倍数という性質を利用しています。Elixirには、Charlistは、int型のlistと同じ型という性質があるため、一文字ずつ48を引いて(ASCII -> int)再帰的に処理しています。

Buzz

  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

こちらは単純に最後が5か0かで判断しています。

文字列の結合

  def _notFB("", num), do: Integer.to_charlist(num)
  def _notFB(some, _), do: some

今までの関数は、該当する場合、Fizzを該当しない場合Buzzを返していました。この関数で、から文字列でない場合はその文字列を、から文字列sの場合は数字を返却しています。

実行文

Enum.map(1..100, fn(x) -> IO.puts FizzBuzz.fizzBuzz(x) end)

なんのひねりもない繰り返しです。

まとめ

FizzBuzは楽しい

1
0
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
1
0