数学を通して身に付けるべき「サボる」力

  • 27
    いいね
  • 0
    コメント

How To Become A Hacker(ハッカーになる方法)

How To Become A Hacker にこんなことが書かれています。

Q: Do I need to be good at math to become a hacker?
(ハッカーになるには数学が得意じゃないとダメですか ?)

A: No. Hacking uses very little formal mathematics or arithmetic. In particular, you won't usually need trigonometry, calculus or analysis (there are exceptions to this in a handful of specific application areas like 3-D computer graphics). Knowing some formal logic and Boolean algebra is good. Some grounding in finite mathematics (including finite-set theory, combinatorics, and graph theory) can be helpful.
(いえいえ、ハッキングは形式的な数学や算数はほとんど使いません。具体的には、三角関数だの微積分だの解析だのはふつうは要りません(3-D コンピュータグラフィックスなど一部の限られたアプリケーション分野は例外です)。形式論理やブール代数を多少知っているのはいいことです。有限数学の基礎(有限集合論、組み合わせ数学、グラフ理論)も役に立ちます。)

Much more importantly: you need to be able to think logically and follow chains of exact reasoning, the way mathematicians do. While the content of most mathematics won't help you, you will need the discipline and intelligence to handle mathematics. If you lack the intelligence, there is little hope for you as a hacker; if you lack the discipline, you'd better grow it.
(もっと重要なことがあります。数学者がやるのと同じように、論理的に考えて、厳密な理由づけの連鎖をたどれる必要があります。ほとんどの数学の中身は役にたちませんが、数学を扱えるだけの規律と知性は必要です。知性がなければ、ハッカーとしては絶望です。規律が身に付いていなければ、それを育んでおかないとどうしようもありません。)

(和訳は How To Become A Hacker: Japanese より引用)

「サボる」力とは

数学の一つ一つの理論はとても面白いものですが、それにも増して重要なのが、今回のテーマである「数学を通して『サボる』力を身に付けること」です。私個人は、この「『サボる』力」こそ「数学を扱えるだけの規律と知性」の中でも最も重要な要素と考えています。数学は断じて「計算力を身に付ける学問」ではありません。

では「『サボる』力」とは何なのか ? いくつかの実例を通して見てみましょう。

ある因数分解から見えるもの

$x^6 - y^6$ という式を因数分解してみましょう。

\begin{align}
x^6 - y^6
&= (x^2)^3 - (y^2)^3 \\
&= (x^2 - y^2)(x^4 + x^2 y^2 + y^4) \\
&= (x + y)(x - y)(x^4 + 2x^2 y^2 + y^4 - x^2 y^2) \\
&= (x + y)(x - y)\{(x^2 + y^2)^2 - (xy)^2\} \\
&= (x + y)(x - y)(x^2 + xy + y^2)(x^2 - xy + y^2).
\end{align}

かなり技巧的な変形をしていますね。これがスラスラ出来る人は、かなりの計算力をお持ちだと思います。しかし、次のように変形すれば、もっと簡単に計算できるのです。

\begin{align}
x^6 - y^6
&= (x^3)^2 - (y^3)^2 \\
&= (x^3 + y^3)(x^3 - y^3) \\
&= (x + y)(x^2 - xy + y^2)(x - y)(x^2 + xy + y^2).
\end{align}

もちろんどちらも正解で満点なのですが、数学を通して本当に身に付けるべき力とは、「前者のような難しい計算をこなす力」ではなく「後者のように簡単に計算できる方法を見つける力」なのです。

これはプログラマでなくとも身に付けるべき力だと思いますが、とりわけプログラマには「ある問題を『コンピューターがより簡単に解決できる問題』に置き換える力」が求められます。次の例は「ある問題をより簡単な問題に置き換えることで簡単に解決できる問題」の良い例かと思います。

「余事象」という考え方から見えるもの

次のような問題を考えてみましょう。

歪みのないコイン1を 100 回投げるとき、少なくとも 1 回は表が出る確率を求めよ。

まさかこの問題を

  • 表がちょうど 1 回出るとき
  • 表がちょうど 2 回出るとき
  • ...
  • 表がちょうど 100 回出るとき

のように場合分けして解く人はいないと思います。解けなくはないですが面倒ですし、(仮にコンピューターに解かせるとして)この方針に従ってコーディングするのも…まぁ、できなくはないでしょう2が、ちょっと遠慮したいですよね。

普通は余事象を使って問題をより簡単なものに置き換えます。「表が 1 回も出ない」以外のパターンは全て「少なくとも 1 回は表が出る」という条件を満たすわけですから、1 から「表が 1 回も出ない確率 = 裏が 100 回出る確率」を引けばよいとわかります。答は言うまでもなく $1 - (\frac12)^{100}$ です3

ドミノタイリング問題

これまでの例よりもよりはっきりと「サボる」力の効果が出る問題として「ドミノタイリング問題」というのがありまして、これに関しては上杉周作さんが次のような分かりやすい記事を書いてくださっています。

「プログラミング」と「プログラミング的思考」の違いを、分かったつもりになれるヒント

しらみつぶし法で解こう(もしくはコンピューターに解かせよう)と思ったら、とんでもない計算量になってしまう4ことがお分かりいただけると思います。

まとめ

まとめると、「サボる力」とは、「楽して答を得るために、問題をより簡単なものに置き換える力」です。楽をするために労力を費やすとは一見矛盾しているようですが、その方が結果的には楽になるので、ここの労力を惜しんではいけません。

そして、こうした力を養うためには、やはり数学を学ぶ必要があります。一つ一つの理論に精通する必要はありませんが、少なくともそれらを追い回し、多少なりとも手懐けることを繰り返すことによって養われる力であると、私は考えています。

「サボる」プログラマは良いプログラマである

「サボる」力が何故そんなに重要なのか、その答が「プログラマの三大美徳」の中にあります。

プログラマの三大美徳は

  1. 怠慢(Laziness)
  2. 短気(Impatience)
  3. 傲慢(Hubris)

である5と言われます。並んでいるこの順に重要であり、すなわち「怠慢」は最も重要な美徳とされています。

全体の労力を減らすために手間を惜しまない気質。
この気質の持ち主は、役立つプログラムを書いてみんなの苦労を減らしたり、同じ質問に何度も答えなくてもいいように文書を書いたりする。
よって、プログラマーの第一の美徳である。

(プログラマーの三大美徳 | Money Forward Engineers' Blog より引用)

数学を通して、「『如何にしてサボるか』について労力を惜しまない」力を身に付け、プログラミングに活かしていただければと思います。


  1. 表と裏の出る確率が等しく $\frac12$ であるという意味。 

  2. 最近のプログラミング言語だと数学系パッケージに二項係数を計算するメソッドとか用意されてたりするからそんなに難しくもない ? (苦笑) 

  3. 余談ですが、この値は 0.99999999999999999999999999999921... と限りなく 1 に近いです。つまり 100 回もコイン投げたらさすがに 1 回くらいは表出るでしょ、ってことです。 

  4. 記事にも書いてありますが、$12 \times 12$ マスで約 5 京($= 5 \times {10}^{16}$)通りあるそうです。 

  5. Perl の生みの親 Larry Wall による。