Technically Impossible

Lets look at the weak link in your statement. Anything "Technically Impossible" basically means we haven't figured out how yet.

必修アルゴリズム

身近な疑問を解いて身につける 必修アルゴリズム
初心者向け、初学者向けの書籍、特にその良書を見つけるのは難しい。まず大前提として、読者と書籍との相性がある。いくら識者、経験者が勧めたところで、同一の内容を伝えていながら、表現一つで理解できたり、できなかったり、ということがあるのだから、相性が悪ければどうしようもない。
いくら内容が良くとも、読書体験が良好でなければ、それは理解の妨げに作用するはずだ。

読者自身が良書を見つけられるとすれば、それは初心者、初学者という前提と相反する要素だ。知識がないから初心者、初学者なわけで、その分野における良書を見分けられるのであれば、すでに初心者、初学者の域は脱していることだろう。
結局のところ、初心者、初学者向けの書籍、特に良書というものは、手当たり次第に目を通して知識を蓄え、その蓄積を頼りに自らの感覚で良書を識別、判断する結果論でしかないのではないだろうか。

いわゆる古典的、教科書的な名著を除いて、特に初心者向けに書き上げられた技術書とは、どのような特性を備えたものだろう。個人的に思い当たるのは、

  • とにかく理解させるために、たとえ表現が冗長であっても徹頭徹尾、言葉を尽くす。
  • 読むだけで済まさせない
    • 理解するために考えることを要求する
    • 理解するために作業を伴う
  • コードに手を入れる、書き換える余地がある

今回取り上げる『必修アルゴリズム』は、そのような特性を備えた初心者向けの技術書だった。


本書は初心者、初学者向けにアルゴリズムを紹介する書籍だ。「身近な疑問を解いて身につける」とタイトルに添えられている様に、身近な話題と関連したアルゴリズムと、そのロジックを紹介している。次のアルゴリズムが取り上げられている。

フェアフィールドの公式 万年カレンダー
過半数判定
状態遷移図、状態遷移表 メールアドレスの正誤判定
エレベータのアルゴリズム 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講座」でも触れられていない。

  • 定数、グローバル変数を整理する
  • 処理構造を見直し、更に構造的にする
  • if-elif-else構文を、match-case構文に書き換える
  • 多重ループを再帰処理に書き換える

ソフトウェアをインストールするように、書いてあることに目を通すだけで理解し、実用できるようになれば願ったりなのだが、実際には理解止まりなのが現実だろう。知っているだけでなく、できるようになるには、このようなことに自発的に対応する必要がる。そうすることでロジックに対する理解が深まるだけでなく、より実践的な知識が身についていく。