初心者向け、初学者向けの書籍、特にその良書を見つけるのは難しい。まず大前提として、読者と書籍との相性がある。いくら識者、経験者が勧めたところで、同一の内容を伝えていながら、表現一つで理解できたり、できなかったり、ということがあるのだから、相性が悪ければどうしようもない。
いくら内容が良くとも、読書体験が良好でなければ、それは理解の妨げに作用するはずだ。
読者自身が良書を見つけられるとすれば、それは初心者、初学者という前提と相反する要素だ。知識がないから初心者、初学者なわけで、その分野における良書を見分けられるのであれば、すでに初心者、初学者の域は脱していることだろう。
結局のところ、初心者、初学者向けの書籍、特に良書というものは、手当たり次第に目を通して知識を蓄え、その蓄積を頼りに自らの感覚で良書を識別、判断する結果論でしかないのではないだろうか。
いわゆる古典的、教科書的な名著を除いて、特に初心者向けに書き上げられた技術書とは、どのような特性を備えたものだろう。個人的に思い当たるのは、
- とにかく理解させるために、たとえ表現が冗長であっても徹頭徹尾、言葉を尽くす。
- 読むだけで済まさせない
- 理解するために考えることを要求する
- 理解するために作業を伴う
- コードに手を入れる、書き換える余地がある
今回取り上げる『必修アルゴリズム』は、そのような特性を備えた初心者向けの技術書だった。
本書は初心者、初学者向けにアルゴリズムを紹介する書籍だ。「身近な疑問を解いて身につける」とタイトルに添えられている様に、身近な話題と関連したアルゴリズムと、そのロジックを紹介している。次のアルゴリズムが取り上げられている。
フェアフィールドの公式 | 万年カレンダー |
過半数判定 | |
状態遷移図、状態遷移表 | メールアドレスの正誤判定 |
エレベータのアルゴリズム | HDDの磁気ヘッド移動アルゴリズム |
動的計画法 | 最小枚数のコイン |
ダイクストラ法 ベルマン=フォード法 |
最短経路探索 |
ゲール=シャプレー法 | 安定マッチング |
k-means k-means++ エルボー法 |
クラスタリング |
先に紹介した三つの特性に沿って紹介すると、次のような特徴がある。
とにかく理解させる
まず特徴的なのが、とにかく理解させるために言葉を尽くしていることだ。それは本文だけでなく、step by stepで図示した処理過程、Pythonで記述されたサンプル・コードにも表れている。処理の流れとロジック構造を明確に示すために、とにかく全てが冗長なのだ。サンプル・コードは特に顕著で、一切の省略記法を用いることなく書き下され、再帰できるところも愚直にループを重ねている。
たとえば、このような具合だ。あくまでもロジックの理解を優先させるために、コードが理解の妨げにならないための配慮だろう。
for num 10 in range(0, max10 + 1): for num 50 in range(0, max50 + 1): for num 100 in range(0, max100 + 1): for num 400 in range(0, max400 + 1): for num 500 in range(0, max500 + 1):
しかしこれが後述する特性に通じており、理解から習得へ通じる貢献要素となっている。
読むだけで済まさない
そもそもアルゴリズムが実施している作業というのは、人間にとって直観的に理解しがたいものだ。文章だけでは伝わりにくいからこそ、処理過程を図示して理解を深めさせようとする。そして、それはただ眼で見て分かり易くするだけでなく、読者の手作業を伴うものだ。
たとえば、次の引用図だ。処理順序に沿って動的計画表を埋め、状態遷移図に沿って、一文字一文字の処理過程を辿ることになる。
理解できたからプログラムが書けるとは限らないが、少なくともアルゴリズムがどのような処理をしているのかは、自ずと理解できるようになるはずだ。
コードを書き換える
先に示したように、本書のサンプル・コードはとても冗長に記述されており、書き直す余地が十分にある。前提としている動作環境はAnaconda*1なので、最新版でもPython 3.9を利用することになる。そのため、3.10以降で採用されたmatch-case構文*2が用いられていない。また巻末の補章「Python講座」でも触れられていない。
ソフトウェアをインストールするように、書いてあることに目を通すだけで理解し、実用できるようになれば願ったりなのだが、実際には理解止まりなのが現実だろう。知っているだけでなく、できるようになるには、このようなことに自発的に対応する必要がる。そうすることでロジックに対する理解が深まるだけでなく、より実践的な知識が身についていく。