okuzawatsの日記

Android / Kotlin / GitHub Actions Enthusiast 🤖

SwiftでFizzBuzz

profile

書いている人 モバイルアプリケーションアーキテクト(Android)として働いています。モバイルアプリケーションのアーキテクチャ、自動テスト、CI/CDに興味があります。もっと詳しく

Swiftに入門していきたいので、FizzBuzzを書いて肩慣らししていきます。FizzBuzzのルールについてはWikipediaを参照してください。

FizzBuzz

まずは普通に switch で書こうとしたわけですが、Swiftの switch は値を返す式ではなく、値を返さない文です。そのため、Fizzを返すパターン、Buzzを返すパターン、FizzBuzzを返すパターン、それ以外のパターンのすべてで return を書く必要があることに気付きます。悪くないですが、そんなに return を書きたくないです。

ということで、var で文字列を宣言し、3で割り切れる場合は Fizz を、5で割り切れる場合は Buzz を文字列に追加していくアプローチを取ります。3で割り切れ、かつ5でも割り切れる場合は、FizzBuzz の両方が追加されて FizzBuzz となる仕組みです。最初に書いたものがこれです。

func fizzbuzz(n:Int) -> String {
  var s = ""
  if n % 3 == 0 { s += "Fizz" }
  if n % 5 == 0 { s += "Buzz" }
  return s.isEmpty ? String(n) : s
}

(1...100)
  .map { fizzbuzz(n:$0) }
  .forEach { print($0) }

悪くないです。

ここから文字列を削る作業を始めていきます(これは趣味ですが、言語について調べることになるのでいい勉強になります)。

まず n % 3 == 0 としている箇所ですが、整数同士の剰余は常に0以上であるという性質を利用すると、n % 3 < 1 と書いても良いことに気が付きます。5についても同様です。

func fizzbuzz(n:Int) -> String {
  var s = ""
  if n % 3 < 1 { s += "Fizz" }
  if n % 5 < 1 { s += "Buzz" }
  return s.isEmpty ? String(n) : s
}

// 略

String(n) は、文字列に展開する記法を用いて "\(n)" と書いた方が短いです。

func fizzbuzz(n:Int) -> String {
  var s = ""
  if n % 3 < 1 { s += "Fizz" }
  if n % 5 < 1 { s += "Buzz" }
  return s.isEmpty ? "\(n)" : s
}

// 略

さらに、 s.isEmpty は空文字 "" との比較で十分です(業務でSwiftを書く場合は s.isEmpty を使うことでしょう…)。

func fizzbuzz(n:Int) -> String {
  var s = ""
  if n % 3 < 1 { s += "Fizz" }
  if n % 5 < 1 { s += "Buzz" }
  return s == "" ? "\(n)" : s
}

// 略

丁寧に fizzbuzz 関数を定義するのはやめて、ループの中ですべての処理を書くようにしてしまいましょう。

(1...100).forEach {
  var s = ""
  if $0 % 3 < 1 { s += "Fizz" }
  if $0 % 5 < 1 { s += "Buzz" }
  print(s != "" ? s : "\($0)")
}

forEach をやめて素朴に for を使うようにすると、 $0 の代わりにインデックスが使えるようになったりするので少し削れます。

for i in 1...100 {
  var s = ""
  if i % 3 < 1 { s += "Fizz" }
  if i % 5 < 1 { s += "Buzz" }
  print(s != "" ? s : "\(i)")
}

自分にはこれ以上削れません。実行してみます。

% swift -v 
Apple Swift version 5.7.2 (swiftlang-5.7.2.135.5 clang-1400.0.29.51)
% swift fizzbuzz.swift
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
以下略

GitHub Actions

ついでに、GitHub Actionsで今回書いたFizzBuzzを実行してみます。GitHub Docsに、「特定のバージョンのSwiftを使用するには、fwal/setup-swiftを使え」(Ref.2)と書いてあるので、使います。

name: FizzBuzz

on:
  push:
    branches:
      - main

jobs:
  fizzbuzz:
    runs-on: macos-latest
    steps:
      - uses: actions/checkout@v3
      - uses: fwal/setup-swift@da0e3e04b5e3e15dbc3861bd835ad9f0afe56296
        with:
          swift-version: "5.7.2"
      - name: do fizzbuzz
        run: swift fizzbuzz.swift

プロジェクト全体はGitHubの以下のリポジトリに公開してあります。

Reference

  1. Fizz Buzz - Wikipedia(最終アクセス日:2023/02/26)
  2. Swift のビルドとテスト - GitHub Docs(最終アクセス日:2023/02/26)

Related