» 詳しい使用方法や、エラーで展開できない際の対応方法などはこちら
FizzBuzz の答えを表示するプログラム
プログラミングの練習問題としても有名な、FizzBuzz(フィズバズ)の答えを表示するプログラムの例です。
コードは Vnano で記述していますが、コード解説 の項目において、C言語/C++/Java言語で書いたコードも配布しています。 また、Vnano は VCSSL のサブセットであるため、拡張子を「 .vcssl 」に変えればそのままVCSSLのコードとしても動きます。
スポンサーリンク
使用方法
ダウンロードと展開(解凍)
まず、PC(スマホは未対応)で上の画面の「 ダウンロード 」ボタンを押してください。 するとZIP形式で圧縮されたファイルがダウンロードされます。
その後、ZIPファイルを右クリックして「すべて展開」や「ここに展開」などで展開(解凍)してください。 展開が成功すると、ZIPファイルと同じ名前のフォルダができ、その中にZIPファイルの中身が入っています。
» 展開がエラーで止まってしまう場合や、ファイル名が文字化けしてしまう場合は…
プログラムの起動
Windows をご使用の場合
上記でZIPファイルを展開したフォルダ内にある、以下のバッチファイルをダブルクリック実行してください:
もしプログラムを書き変えながら使いたい場合は、代わりに「 VCSSL_Editor__プログラム編集はこちら.bat 」を実行してください。
正常に起動できると、初回のみ、Java実行環境を入手するか等を尋ねられるので、適時答えて済ませると、プログラムが起動します。 2回目以降はすぐに起動します。
Linux 等をご使用の場合
ZIPファイルを展開したフォルダ内へコマンドライン端末で cd して、以下の通り入力して実行してください:
(プログラムの内容を書き変えながら使いたい場合は、代わりに VCSSL_Editor.jar を実行)
» javaコマンドが使用できない等のエラーが表示される場合は…
起動後
起動すると、黒いウィンドウが立ち上がり、そこに FizzBuzz の答えが表示されます。
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
...
表示される内容の各行が、1から100までの各数字に対する FizzBuzz の答えを表しています。
上限の数字(100)を変えるには、コードが書かれたファイル「 FizzBuzz.vnano 」を適当なテキストエディタ(メモ帳でも可)で開いて、中にある以下の行の数字を書き換えてください:
題材解説
そもそも FizzBuzz とは?
本来の FizzBuzz は、人間が行う遊びの一種で、以下のようなものです:
- 1, 2, ... と順に数字を数えて(唱えて)いく
- 数字が 3 の倍数の時は、数字の代わりに「 Fizz(フィズ)」と唱える
- 数字が 5 の倍数の時は、数字の代わりに「 Buzz(バズ)」と唱える
- 数字が 3 と 5 の両方の倍数になっている時は、「 FizzBuzz(フィズバズ)」と唱える
本来は複数人でやって、間違えた人は脱落していくルールのようですね。 確かに、一見簡単そうですが、順番を高速で回すと混乱して盛り上がりそうではあります。
プログラミングの練習課題としての FizzBuzz
と紹介しつつ、恐らく日本で FizzBuzz を知っている人は、ほとんどがプログラミングの初歩的な練習問題として知ったのではないでしょうか。
というのも、「 1から順に数え上げていく 」という点や、先に述べたルールなどが、 まさに「 ループと条件分岐をちゃんと理解していれば書けて、何かを勘違いして理解していると苦戦する、絶妙な内容の課題 」になっているためです。
また、正しく理解していたとしても、「 複数の if 文と else 文を組み合わせて、思い通りの挙動を実現する感覚 」などは、 if/else 文を学んだだけの時点では身についておらず、実際に具体的な課題について、手を動かしてトライ&エラーで練習してみないと、なかなか体得できません。
FizzBuzz は、まさにその最初の「 具体的な課題 」のレベルとして絶妙なんだと思います。
という事で、もしあなたが何かの課題で FizzBuzz について調べてこのページに辿り着いた場合は、 後述のコード解説を見る前に、ぜひ1時間くらい自力でコードを記述するのに挑戦してみてください。 言語は何でも大丈夫です。 色々試してうんうん悩んでいるその時間が、きっと何より上達を生んでくれると思います。
その際に、このサイト内の、以下の2つのページが参考になるかもしれません:
上記はプログラミング言語 VCSSL/Vnano のガイドですが、シンプルなC言語系の文法なので、 他のC言語系の言語においても恐らく参考になると思います。
プログラミングでは別の遊び方も(コードゴルフ)
ところで、それならプログラムをある程度バリバリ書ける段階なら、FizzBuzz なんてお呼びでない?…かと言うと、意外とそうでもありません。
例えば、プログラマー/エンジニアが複数人居る場面で、何か暇つぶしや余興をしようという時に、通称コードゴルフと呼ばれる遊びがあります。 これは、「 決められた問題を解くコードを、いかに少ない文字数で書くか 」というものです。
全員がコードゴルフに慣れている場合は、いきなり複雑な課題から入ったりもしますが、「コードゴルフは初めて」という人が居る場では、「 とりあえず FizzBuzz から 」みたいな形でスタートしたりします。 FizzBuzz はコードゴルフの最初の一歩としても絶妙な課題になっているためです。 さらに、「剰余演算子(%)使わない縛り」とか「条件分岐使わない縛り」といったように、追加ルールで難易度を調整できる余地も多いです。
コード解説コーナーの最後に、Javaで書いた FizzBuzz コードゴルフの解答例を掲載していますので、 「コードゴルフやった事ない」という人は、ぜひ数分〜数十分くらい自力で書いてみてから、見比べてみてください。きっとハマる人は楽しめますよ。
コード解説
ここからは、プログラムのコード内容を見ていきましょう。
コード全体
このプログラムのコードはVnanoで記述されています。 VnanoはC言語系のシンプルな文法を持っているので、C系の言語に触れられた事のある方なら、 コメントを参考にしながらコード内容を比較的簡単に追う or 改造する事ができると思います。
一応は、C/C++/Java言語版のコードも併せて用意していますので、必要な方は下記のリンクを右クリックしてダウンロードしてください。 解説はVnanoのコードで行いますが、他の各言語への読み替えは簡単だと思います。
まずは、コード全体を見てみましょう:
全体でも30行に満たない短いコードですね。以下では、各部を掘り下げてみていきます。
先頭行
一番最初の「 coding UTF-8; 」の行は、ファイルの文字コードを明示しています。無くても動きますが、環境によっては文字化けしたりするので、その予防です。
4行目: 数える数の上限を格納する変数「 max 」を宣言
これはコメントそのままで、特に何か追加で説明する必要もないと思います。強いて何か言うなら、for 文の中で「 i<=100; 」みたいにベタ書きするよりは、こうした方が多少行儀がいい、くらいでしょうか。
6行目〜: 1 から順に数え上げるループ
さあ、練習課題として FizzBuzz に挑戦している人にとっての「 最初の壁 」です。王道的なド直球の for 文のループです。 何をやっているか、すぐに分かったでしょうか? 自信がない方は、以下を読んでみてください:
この箇所では、カウンタ変数「 i 」の値に 1 ずつ足しながら、それが 100 になるまで、{ ... } の中の処理をくり返しています。
実際に、{ ... } の中身を単純に { println(i); } などに置き換えてみると、1 から 100 までの数字が表示されるはずです。
ここから先は、カウンタ変数 i の値を単に表示するのではなく、その値に応じて異なる内容を表示するように、{ ... } 内に条件分岐を入れ込んでいくイメージです。
9行目〜: i が 3 と 5 の両方の倍数になっている場合の処理
さてその最初、9行目〜の処理です。いきなりですが、ここは恐らく FizzBuzz における2つめの壁で、シンプルなようでいて、複数の重要な要素が入っています:
この箇所で何をやっているかというと、「 3 と 5 の両方の倍数になっている場合 」の処理です。
ここで使っている if 文では、(...) 内の条件が成り立っている場合に、{ ... } 内が実行されます。 つまり上では「 FizzBuzz 」と表示する処理(println)が実行されます。 これ自体は恐らく、大半の人にとっては、よく分かっている事だと思います。
一方で、その条件の内容「 i%3 == 0 && i%5 == 0 」は、少し混乱した人も多いのではないでしょうか。 これは「 3 と 5 の両方の倍数になっている時に成立(true) 」という条件を表しています。
少しかみ砕いて説明しましょう。まず「 % 」は「 割った余り 」を求める演算子(記号)です。例えば 10 % 2 は 0、10 % 3 は 1、10 % 7 は 3 です。 そして、「 ある数が X の倍数かどうか 」というのは、「 X で割った余りが 0 となるかどうか 」として判断可能です。 実際に色々な数で試してみてください。これはプログラミングでよく登場する、いわばイディオム的な判定処理です ※。
つまりここでは、「 i%3 == 0 」が「 3 の倍数かどうか 」の判定、「 i%5 == 0 」が「 5 の倍数かどうか 」の判定になっているわけです。
もう一つの大きな存在は「&&」です。これは、「 その右側と左側の条件が、両方とも成立している場合のみ、全体で条件成立とする 」ためのものです。 つまり、「 i%3 == 0 」と「 i%5 == 0 」とを、「 && 」でつなぐ事によって、3 と 5 の「 両方の 」倍数になっているかを判定しているわけです。
※ このイディオム的な判定処理を知らないと、例えば「 中にもう一つカウンタ変数 n のループを追加して、n を 3 ずつ増やしていって、どれかの n が i と一致すれば、i は 3 の倍数だ! 」みたいな判定処理を書く(書いた事がある)かもしれません。
でも、プログラミングを始めた最初のうち(または、同種の課題に初めて出会った時)は、それは全く恥ずかしい事ではないと思います。 最初のうちは、とにかく「どうすれば実現できるか」の処理方法(アルゴリズムといいます)を考えて、思いついたら書いてみる、を繰り返してみる事が貴重な経験だと思います。 そういった過程でしか体得できない大切な感覚が、恐らくたくさんあるからです。
そして、「ここは何かもっといい方法がありそうな気がする」と感じ取るアンテナが育ってきたら、その時は積極的に調べてみましょう。大抵、もっと遥かにシンプルなり高速なりの方法が存在します。
13行目〜: 上記以外で、3 の倍数になっている場合の処理
さて、その後に続くコードです:
一見、さっきよりシンプルですね。if 文の (...) 内に書かれた「 i%3 == 0 」も既に登場した通りで、「 3 の倍数かどうか 」を判定する条件です。 成立する場合に { ... } 内が実行されますが、そこで「 Fizz 」と表示する処理(println)を記述しています。
「 なんだ、もう全て知ってる事じゃないか 」と思いました? でも要注意です。ここでも新しい要素がしっかり登場しています。
それは、if の前に「 else 」が付いている事です。この else が付く事によって、 ここは「 前の(3と5の両方の倍数になっている場合の)if 文の条件が成立しなかった場合のみ、条件判定/処理対象となる 」 という振る舞いになります(※ else if が複数連なる場合の挙動は後述)。 逆に言えば、直前の if 文の条件が成立した場合は、ここの if 文は、その条件内容にかかわらず読み飛ばされます。
つまるところ、ここでの処理は、「 i が 3 と 5 の両方の倍数にはなっていない場合で、かつ、3 の倍数にはなっている場合 」に {...} 内が処理されます。
このあたりが少し自信がない、という方は、併せて以下を参照してみてください:
19行目〜: 上記以外で、5 の倍数になっている場合の処理
その後は、ほぼ同じ形の処理がもう一回登場します:
違いは「 3 」が「 5 」になっている点で、つまり 5 の倍数の場合の処理を行っています。
ここでも「 else if 」のコンボが登場していますね。 それによってここは、 「 ここよりも上に続く if や else if が、どれも成立しなかった場合にのみ、条件判定/処理対象となる 」という挙動になります。
つまり結局、i が 5 だけの倍数の時に、「 Buzz 」と出力する、という処理になります。
24行目〜: どの倍数にもなっていない場合の処理
さて、コードのラストです:
今度は if が無く、else だけですね。また新しいパターンです。
この部分は、「 ここよりも上に連なる if や else if が、どれも条件成立しなかった場合に、この else の {...} 内の処理が実行される 」という挙動になります。
つまるところ、ここは「 3と5の倍数でもなく、3の倍数でもなく、そして5の倍数でもない 」という場合に実行される処理になっています。 そして、そこでは FizzBuzz のルールに基づいて、数字 i の値をそのまま表示する処理(println)を記述しているわけです。
ところで実際のプログラムでは、この FizzBuzz プログラムのように、「 if から始まり、複数の else if が連なって、最後に else で終わる 」というパターンの処理は非常によくあるものです。 従って、この連鎖がどう振る舞うかのイメージを、感覚に染み込ませておくと便利です。
最後に
コードの解説は以上です。
今回の内容は、実はGitHub上で Vnano処理系のソースコードリポジトリ を整理(掃除)していた際に、 削ったサンプルコードをここにアップして再利用しようと思ったのが発端でした。
それに際して、FizzBuzz のコード単体では寂しいので、「 プログラミングの練習課題としてよく使われる 」などといった説明を追加して、 コード解説も、プログラミング入門時くらいを想定した視点から書いてみた次第です。
しかし、改めてそういった視点で見ながら説明してみると、FizzBuzz は本当に基本要素が絶妙に詰まっていて、かつ、それぞれが無駄なく登場する、という事に驚きました。 本当にすごい絶妙さですよね。もともと人間用のゲームだったものが、偶然こんなに完成度の高いプログラミング練習課題になっているという。見直しました。
さて、題材解説の項目で触れたコードゴルフのJava解答例についてですが、以下の通りです:
上記を適当な Java コード内にコピペして実行すると、FizzBuzz の結果が出力されるはずです。 文字数は90文字です。即席で書いたものなので、比較的ストレートな内容で、恐らくまだまだ削れるはずです。 でも、ここで削りすぎると面白くなくなるので、興味が沸いた方は、ぜひあなた自身でもっと削ってみてください。
横に複数人いる場合は、「%」演算子を使わない縛りで競うと、人によって方法がばらけて楽しめます。
ライセンス
このVCSSL/Vnanoコード( 拡張子が「.vcssl」や「.vnano」のファイル )は実質的な著作権フリー(パブリックドメイン) である CC0 の状態で公開しています※。 記事中にC言語/C++/Java言語などでのサンプルコードが掲載されいてる場合は、それらについても同様です。 そのままでのご利用はもちろん、改造や流用などもご自由に行ってください。
※ ただし、このコードの配布フォルダ内には、ダウンロード後すぐに実行できるように、 VCSSLの実行環境も同梱されており、そのライセンス文書は「 License 」フォルダ内に同梱されています (要約すると、商用・非商用問わず自由に使用できますが、使用の結果に対して開発元は一切の責任を負いません、といった具合の内容です)。 配布フォルダ内の各構成物の一覧やライセンスについては「 ReadMe_使用方法_必ずお読みください.txt 」をご参照ください。
※ Vnano の実行環境については、別途スクリプトエンジンのソースコードも一般公開しており、 何らかのソフトウェア内に組み込んでご利用いただく事も可能です。詳細はこちらをご参照ください。
この記事中の商標などについて
- OracleとJavaは、Oracle Corporation 及びその子会社、関連会社の米国及びその他の国における登録商標です。文中の社名、商品名等は各社の商標または登録商標である場合があります。
- Windows は、米国 Microsoft Corporation の米国およびその他の国における登録商標です。この記事は独立著作物であり、Microsoft Corporation と関連のある、もしくはスポンサーを受けるものではありません。
- Linux は、Linus Torvalds 氏の米国およびその他の国における商標または登録商標です。
- その他、文中に使用されている商標は、その商標を保持する各社の各国における商標または登録商標です。
角度の「度」とラジアンとを相互変換し、図示もするツール |
|
|
45度などの「度」の値と、ラジアンの値とを相互に変換できるツールです。対応する角度の図示もできます。 |
FizzBuzz の答えを表示するプログラム |
|
|
プログラミングの練習問題としても有名な、FizzBuzz 問題の答えを表示するプログラムの例です。 |
Vnano版 | 積分値のグラフ描画用データを出力するプログラム |
|
|
数値的に積分を行い、結果の関数をグラフに描くためのデータを出力するコードです。 |
Vnano版 | 積分値を求めるプログラム (数値積分) |
|
|
矩形法/台形法/シンプソン法を用いて、積分の値を数値的に求めるコードです。 |
入力された数式を積分して値とグラフを表示するツール |
|
|
画面上で数式を入力すると、それを数値的に積分し、値とグラフを表示してくれるGUIツールです。 |
シンプソン法による数値積分 |
|
|
積分の値を数値的に求めます。台形法よりも高精度な方法として、被積分関数を微小区間内で二次関数近似して求めた面積を足しあげる、シンプソン法を使用します。 |
台形法(台形近似)による数値積分 |
|
|
積分の値を数値的に求めます。長方形近似よりも高精度な方法として、台形で近似した微小領域を足しあげる方法を使用します。 |
矩形法(長方形近似)による数値積分 |
|
|
積分の値を数値的に求めます。長方形の短冊(矩形)で近似した微小領域を足しあげる、最も単純な方法を使用します。 |
小数(浮動小数点数)から分数へ近似的に変換するツール |
|
|
小数(浮動小数点数)を、適当な誤差の範囲内で、近い分数に変換してくれるツールプログラムです。 |
円周率1万桁の計算(ガウス=ルジャンドル法) |
|
|
ガウス=ルジャンドル法により、円周率を1万桁まで計算するプログラムです。 |
試し割り法による素数判定ツール |
|
|
試し割り法を用いて、素数判定を行ってくれる簡易ツールです。 |