FizzBuzzで覚えるVBA(いろんなFizzBuzzを紹介するよ)
こんにちは。
派犬事務員のコロです。
FizzBuzzにハマるウサ子
2回目の講座の宿題FizzBuzzにウサ子がドハマりして、毎日のようにいろんなFizzBuzzが送り付けられてきたので、変なの優秀なのを紹介します~。
FizzBuzzとはプログラミングの練習問題のこれ↓
数字を1から順に100までデバッグ出力します。
ただし
・数字が3の倍数のときには数字の代わりに「Fizz」
・数字が5の倍数のときには数字の代わりに「Buzz」
・数字が3の倍数かつ5の倍数のときには代わりに「FizzBuzz」
と出力するようにしてください。
多分全部で20~30個あったと思う。
新しい構文が出てくるたびにFizzBuzzが送られてきて、ウサ子曰く「FizzBuzzでVBAを覚えた」らしい。
VBAを勉強してるけど「なかなか使うところがない」という人はいろんなFizzBuzzを考えてみよう。
回答1(足し算バージョン)
習得できると思われるスキル
①ループ
②If文
へんてこレベル:★
Sub FizzBuzz1() Dim x As Long: x = 3 Dim y As Long: y = 5 Dim z As Long: z = x * y Dim i As Long For i = 1 To 100 If i = z Then Debug.Print "FizzBuzz" x = x + 3 y = y + 5 z = z + 15 ElseIf i = y Then Debug.Print "Buzz" y = y + 5 ElseIf i = x Then Debug.Print "Fizz" x = x + 3 Else Debug.Print i End If Next i End Sub
おお!Modを使わないタイプ!
全部足し算で考える。
回答2(ブール比較バージョン)
習得できると思われるスキル
①If文(Trueのとき処理を行う)
へんてこレベル:★
Sub FizzBuzz2() Dim x As Boolean Dim y As Boolean Dim z As Boolean Dim i As Long For i = 1 To 100 x = i Mod 3 = 0 y = i Mod 5 = 0 z = i Mod 15 = 0 If z = True Then Debug.Print "FizzBuzz" ElseIf y = True Then Debug.Print "Buzz" ElseIf x = True Then Debug.Print "Fizz" Else Debug.Print i End If Next i End Sub
「IF 式 Then」の式がTrueのとき処理を行う、とういうのを理解していて良い。
「 If z = True Then」は、zはTrueなので「 If z Then」と書くのがスマートかも。
回答3(周期バージョン)
習得できると思われるスキル
①Select Case文
Select Case文の優れているところは、Orで繋ぐ条件式が複数の場合はカンマ「,」で繋げて書けるトコ。
へんてこレベル:★
Sub FizzBuzz3() Dim i As Long Dim cnt As Long Dim loopcnt As Long For i = 1 To 100 cnt = cnt + 1 Select Case cnt Case 3, 6, 9, 12 Debug.Print "Fizz" Case 5, 10 Debug.Print "Buzz" Case 15 Debug.Print "FizzBuzz" cnt = 0 loopcnt = loopcnt + 1 Case Else Debug.Print cnt + 15 * loopcnt End Select Next i End Sub
考え方は、15で一周期。
回答4(掛け算バージョン)
習得できると思われるスキル
①四則演算?
へんてこレベル:★★
Sub FizzBuzz4() Dim x As Long, y As Long, z As Long x = 3 y = 5 z = x * y Dim ch1 As Long, ch2 As Long, ch3 As Long ch1 = 1 ch2 = 1 ch3 = 1 Dim i As Long For i = 1 To 100 If i = z * ch1 Then Debug.Print "FizzBuzz" ch1 = ch1 + 1 ch2 = ch2 + 1 ch3 = ch3 + 1 ElseIf i = y * ch2 Then Debug.Print "Buzz" ch2 = ch2 + 1 ElseIf i = x * ch3 Then Debug.Print "Fizz" ch3 = ch3 + 1 Else Debug.Print i End If Next i End Sub
掛ける数を増やすのか。なるほど。
回答5(文字列バージョン)
習得できると思われるスキル
①型の変換
へんてこレベル:★★★★★★★★★★
数値を文字列にして判定する。
Sub FizzBuzz5() Dim i As Long Dim stri As String For i = 1 To 100 'iを15で割った数値を文字列に変換する stri = Cstr(Round((i / 15), 10)) If Len(stri) = 1 Then Debug.Print "FizzBuzz" ElseIf Len(stri) = 3 Then Debug.Print "Fizz" Else If Mid(stri, 3, 1) = Mid(stri, 4, 1) Then Debug.Print "Buzz" Else Debug.Print i End If End If Next i End Sub
え?っと思った人。これを見て欲しい。
A列の値を15で割ると、なんか法則があるっぽい。
A列の値が3の倍数のとき:「0.2」「0.4」など文字列にすると3文字(点も1文字になる)
A列の値が5の倍数のとき:「0.333・・」「0.666・・・」など、3文字目と4文字目が同じ値
A列の値が15の倍数のとき:「1」「2」「3」など1文字
おお!!これはなかなか思いつかない!
ちなみに
i=1のとき
stri = Cstr(i / 15)
だと「6.66666666666667E-02」となってしまうので
stri = Cstr(Round((i / 15), 10 ) )と少数以下を10桁にして指数表示にならないように工夫したらしい。
でも、なんで1/15のときだけ指数表示になるんだろう?
回答6(イベントプロシージャもどきバージョン)
習得できると思われるスキル
①Functionプロシージャ
へんてこレベル:★★★★★★★★★
「Functionプロシージャはワークシート関数としても使えますよ。」とは言ったけど、こんなのを作るとは!
↓
「はい、入れました」
↓
「イミディエイトウインドウを見るのね?」
えっ!!イベントプロシージャ?
と思ったらFunction関数!
Function StartFizzBuzz(ByVal x As String) As String If x <> "" Then Call FizzBuzz StartFizzBuzz = "イミディエイトウィンドウを見てね" Else StartFizzBuzz = "A1セルに何か入れて" End If End Function '************************************************************ Sub FizzBuzz() Dim i As Long For i = 1 To 100 If i Mod 15 = 0 Then Debug.Print "FizzBuzz" ElseIf i Mod 5 = 0 Then Debug.Print "Buzz" ElseIf i Mod 3 = 0 Then Debug.Print "Fizz" Else Debug.Print i End If Next i End Sub
B1セルに自作のFuction関数を入れて、引数をA1セルにする。
A1セルに値が入ってる場合はイミディエイトウインドウにFizzBuzzを出力する、という仕組み。
なんか簡易イベントプロシージャって感じ。すごい!
めちゃめちゃびっくり!
回答8(足し算しばりバージョン)
へんてこレベル:★★★★
Sub FizzBuzz8() Dim i As Long Dim num1 As Long Dim num2 As Long Dim num3 As Long Dim num4 As Long num1 = 3 num2 = num1 + 3 num3 = num2 + 3 num4 = num3 + 3 Dim num5 As Long Dim num6 As Long Dim num7 As Long num5 = 5 num6 = num5 + 5 num7 = num6 + 5 Dim x As Long x = 15 For i = 1 To 100 If i = num7 Then Debug.Print "FixxBuzz" num7 = num7 + x ElseIf i = num6 Then Debug.Print "Buzz" num6 = num6 + x ElseIf i = num5 Then Debug.Print "Buzz" num5 = num5 + x ElseIf i = num4 Then Debug.Print "Fizz" num4 = num4 + x ElseIf i = num3 Then Debug.Print "Fizz" num3 = num3 + 1 ElseIf i = num2 Then Debug.Print "Fizz" num2 = num2 + x ElseIf i = num1 Then Debug.Print "Fizz" num1 = num1 + x Else Debug.Print i End If Next i End Sub
回答9(引き算しばりバージョン)
へんてこレベル:★★★★
Sub FizzBuzz9() Dim i As Long Dim x As Long Dim y As Long Dim z As Long Dim th As Long Dim fi As Long Dim ft As Long th = 3 fi = 5 ft = 15 Dim nt As Long Dim tt As Long Dim nn As Long For i = 1 To 100 If i - ft - x = 0 Then Debug.Print "FizzBuzz" nt = 90 x = NewFizzBuzz(x, i, ft, nt) y = x z = x ElseIf i - 5 - y = 0 Then Debug.Print "Buzz" tt = 100 y = NewFizzBuzz(y, i, fi, tt) ElseIf i - 3 - z = 0 Then Debug.Print "Fizz" nn = 99 z = NewFizzBuzz(z, i, th, nn) Else Debug.Print i End If Next i End Sub '*************************************************************************************************** Function NewFizzBuzz(ByVal x As Long, ByVal i As Long, ByVal mn As Long, ByVal cn As Long) As Long Dim cnt1 As Long cnt1 = 100 Dim j As Long Dim l As Long Dim m As Long m = i If x = 0 Then For j = 1 To 100 cnt1 = cnt1 - mn If cnt1 < mn Then Exit For End If Next j j = j - 1 Else For l = 1 To 100 m = m - mn If m = 0 Then Exit For End If Next l For j = 1 To 100 cnt1 = cnt1 - mn If cnt1 < mn Then Exit For End If Next j j = j - l End If Dim k As Long For k = 1 To j cn = cn - mn Next k x = cn NewFizzBuzz = x End Function
回答10(中級バージョン)
習得できると思われるスキル
①ループでのカウンタ変数の指定数の増減
②配列
Sub FizzBuzz10() Dim arr(0 To 100) As String '配列に代入 Dim i As Long For i = 0 To 100 Step 3 arr(i) = "Fizz" Next i For i = 0 To 100 Step 5 If arr(i) = "" Then arr(i) = "Buzz" Else arr(i) = "FizzBuzz" End If Next i 'イミディエイトウインドウに出力 For i = 1 To 100 If arr(i) = "" Then Debug.Print i Else Debug.Print arr(i) End If Next i End Sub
回答11(意味不明バージョン)
Sub FizzBuzz11() Dim i As Long Dim j As Long Dim k As Long Dim l As Long k = 1 For i = 1 To 100 For j = 1 To 5 If j = 1 Then For l = 1 To 3 If i Mod 3 = 0 Then Debug.Print "Fizz" i = i + 1 Else Debug.Print i i = i + 1 End If Next l ElseIf j = 2 Then For l = 1 To 3 If i Mod 3 = 0 Then Debug.Print "Fizz" i = i + 1 ElseIf i Mod 3 = 2 Then Debug.Print "Buzz" i = i + 1 Else Debug.Print i i = i + 1 End If Next l ElseIf j = 3 Then For l = 1 To 3 If i Mod 3 = 0 Then Debug.Print "Fizz" i = i + 1 Else Debug.Print i i = i + 1 End If Next l ElseIf j = 4 Then For l = 1 To 3 If i = 101 Then Exit Sub Else If i Mod 3 = 0 Then Debug.Print "Fizz" i = i + 1 ElseIf i Mod 3 = 1 Then Debug.Print "Buzz" i = i + 1 Else Debug.Print i i = i + 1 End If End If Next l ElseIf j = 5 Then For l = 1 To 3 If i Mod 3 = 0 Then Debug.Print "FizzBuzz" Else Debug.Print i i = i + 1 End If Next l End If Next j j = 1 Next i End Sub
他にも意味不明なのが多数。
確かにFizzBuzz楽しいけど、こんなにハマる人初めて見た・・・。
みんなの凄いFizzBuzzがあったら教えてね。