LoginSignup
24
21

More than 5 years have passed since last update.

Swiftで関数型FizzBuzz

Posted at

Swift その2 の最後の 3 日が投稿されなかったので 3 連投です。

当初のアナウンスによると

カレンダーの25日間がすべて埋まっていることです。投稿を予定していた当日中に書けなかったとしても、カレンダーの最終日である12/25までに投稿されていれば条件を満たすものとします。

とあり、今から投稿しても条件を満たせるか未知数ですが、一応できることはやろうかと。

というわけで Swift で小ネタですが、 FizzBuzz を Swift で関数型っぽく書けば、次のように一つの式で書けます。

(1...100).map { switch ($0 % 3, $0 % 5) {
    case (0, 0): return "Fizz Buzz"
    case (0, _): return "Fizz"
    case (_, 0): return "Buzz"
    case (_, _): return "\($0)"
} }.forEach { print($0) }

実行結果は↓です。

1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
Fizz Buzz
98
...
Fizz
Buzz

しかし、上記のような方法を含め、一般的な方法では本来無限に続くはずの FizzBuzz 列 の最初の方を切り出したものしか作れません。

ListK を使って遅延評価の力を用いれば、次のようにして無限 FizzBuzz リストを得ることができます。

import ListK

// 無限 FizzBuzz リスト
let fizzBuzz: List<String> = List<Int> { $0 + 1 }.map { i in
    switch (i % 3, i % 5) {
    case (0, 0): return "Fizz Buzz"
    case (0, _): return "Fizz"
    case (_, 0): return "Buzz"
    case (_, _): return "\(i)"
    }
}

$0 + 1 して一度 map しているのは、 0 からではなく 1 から始まるようにするためです。

なお、最初の 100 個の要素を取り出して表示するには次のようにします。

fizzBuzz.take(100).forEach { print($0) }
24
21
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
24
21