Swiftに入門していきたいので、FizzBuzzを書いて肩慣らししていきます。FizzBuzzのルールについてはWikipediaを参照してください。
まずは普通に switch
で書こうとしたわけですが、Swiftの switch
は値を返す式ではなく、値を返さない文です。そのため、Fizzを返すパターン、Buzzを返すパターン、FizzBuzzを返すパターン、それ以外のパターンのすべてで return
を書く必要があることに気付きます。悪くないですが、 return
をもう少し減らしたいです。
ということで、var
で文字列を宣言し、3で割り切れる場合は Fizz
を、5で割り切れる場合は Buzz
を文字列に追加していくアプローチを取ります。3で割り切れ、かつ5でも割り切れる場合は、Fizz
と Buzz
の両方が追加されて 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
は空文字 ""
との比較で十分です( 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で今回書いた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の以下のリポジトリに公開してあります。