Pythonで始めるアルゴリズム入門:FizzBuzzとフローチャート


目次

1.はじめに
2.参考図書
3.フローチャート
4.FizzBuzz
5.ツイッターやってます
6.ホームページはこちら

1. はじめに

 私は昔コンピュータサイエンスの学科で「アルゴリズムとデータ構造」をC言語で学んだが、単位はギリギリで、とても苦手意識を持った。セジウィック氏の重厚感のある「アルゴリズムとC」の上下巻を携え、アルゴリズムの1つ1つをC言語で実装していく。C言語自体はカーニハン&リッチーのプログラミング言語Cを用いて学ぶ。カバンも脳みそもパンパンに膨れ上がって消化不良に陥った。今から10年以上前の話である。

 時は経ち、より自然言語に近いプログラムで直感的に書くことができるPython3.xシリーズがそのエコシステムとともに世の中に普及し、プログラミング入門と名乗る教材も多数出版されUdemyをはじめとした動画講義も豊富に提供されるようになった。今コンピュータサイエンスを学ぶ人たちは、本当に恵まれている。今の当たり前は先人たちの挫折と汗と涙の上に形成されたものであるということを忘れないでほしい。

 前置きはここまでとし、本記事では時代の潮流を捉えたPythonによるモチベーションドリブンなアルゴリズム入門の良著に出会ったので、これを噛み砕いて解説したいと思う。

2. 参考図書

「Pythonではじめるアルゴリズム入門(増井 敏克著)」

3. フローチャート

非プログラマとのコミュニケーションにおいて、フローチャートは非常に強力なツールである。その書き方をおさらいしておく。

意味 記号 詳細
開始・終了 処理の開始と終了
処理 処理内容を書く
条件分岐 ifなどの条件を表す。記号の中に条件書く。
繰り返し開始 forなどでの繰り返しを表す。開始(上)、終了(下)を使う。
繰り返し終了
キー入力 利用者によるキーボード入力を表す。

4. FizzBuzz

プログラマーの入社試験としてもよく利用される、FizzBuzz問題を
Pythonとフローチャートで見ていく。

まず、FizzBuzzの問題はこちら

1から100までの数を順に出力するプログラムを書きなさい。
ただし、3の倍数の代わりに「Fizz」を5の倍数の代わりに「Buzz」を3と5の両方の
倍数の代わりに「FizzBuzz」を出力しなさい。

これの問題を順に解いていく。

まず、1から100までforループで回して、その数を
順に出力する、という意味のフローチャートはこうだ!

これをPythonのコードにするとこうだ!range関数はある値からある値までの連続した
数字をある値ずつ足して返す。

range関数の引数は、range(start, stop[, step])となるが、
stop-1までループするので101と書いているのに注意。
また、[,step]はいくつ足していくかで省略すると1足すことになる。

for i in range(1, 101):
  print(i)

では、今度このコードで3の倍数のときは'Fizz', 5の倍数のときは'Buzz',
3と5の倍数のときは'FizzBuzz'と表示してみる。いきなり1から100までだと、
表示が見ずらいので、1から15までで間違いながらトラブルシュートしていく。

for i in range(1, 16):
  if i % 3 == 0:
    print('Fizz')
  elif i % 5 == 0:
    print('Buzz')
  elif i % 5 == 0 and i % 3 == 0:
    print('FizzBuzz')
  else:
    print(i)

Output:

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

ん???んん?? 3と5の倍数もFizzになっている。日本語を上から順にコードに落としたのに、何かおかしい。

それでフローチャートにこの間違ったコードを変換して確認してみる。

このフローチャートで変なのは、条件の判定で、先に3の倍数判定をしているので、
3と5の倍数である、15を流したときには、3で割り切れてしまうので、FizzBuzzが表示されず
Fizzが表示されていたことが確認できる。

ではどうすればよかったのか?

変えたところを、黄色で塗りつぶしてある。
iが3と5で割り切れる、というのを先に判定すると、
15のような数が来たときにFizzが出ちゃうことはなくなり正しく
判定できる。

このように、問題を解く順番で答えは変わる。
これを1から100までとして、コードに起こしてみるとこうだ。

for i in range(1, 101):
  if i % 3 == 0 and i % 5 == 0:
    print('FizzBuzz')
  elif i % 5 == 0:
    print('Buzz')
  elif i % 3 == 0:
    print('Fizz')
  else:
    print(i)

フローチャートはこうだ。

フローチャートで線を交差したら駄目だ。
頭もこんがらがる。最終形はこちら。

プログラマー界隈でフローチャートはオワコンだからUML書こうよという論調もある。
でも、アルゴリズムを考え、非プログラマとコミュニケーションしたり、大規模なコードの
どこが間違っているのかを机上で考えるのに、フローチャートほど便利なものはない、
と個人的には思う。

以上。

5. ツイッターやってます

6. ホームページはこちら