Panda Noir

JavaScript の限界を究めるブログです。

forもifも使わないプログラミング入門3

そろそろforなしifなしでは限界を迎えます。が、まだいけるのでいけるところまで行ってみます。

1から2016までのうち素数であるものを列挙する

これ、実はここまでの知識だけだとどうしても越えられない壁が出てきます。それは、「約数の個数がわからない」からです。

素数というのは、「約数が1とその数自身のみの数」です。ということは約数の個数がカウントできないと判定ができません。

というわけで、新しい概念を導入させてください。

新しい概念、それは .length です。これは数列の個数を数えてくれます。例えば range(1, 2016).length ならば2016と、 range(1, 2016).filter(n => n % 2 === 0) なら1008です。

.lengthを導入できたので、早速コーディングしていきますね。

document.write(range(1, 2016).filter(n =>
    range(1, n).filter(m => n % m === 0).length === 2;
));

こうです。みたままですね。

1から2016までそれぞれを2乗してして総和を求める

これもまた今までの知識だけではできません。「それぞれを2乗」ができないので。そこで、それぞれを2乗するための道具を導入させてください。

それは .map() というものです。mapは日本語だと「地図」ではなく、「写像」のことです。まあよくわからない人はそのままでもOKです。

mapはこういう風に使います

range(1, 2016).map(n => n * n)

f(x) = x2という関数(n => n * n)を、1から2016までそれぞれに適用した新しい数列を返してくれます。あとはいつも通り総和をとって完了です。

range(1, 2016).map(n=>n*n).reduce((a,b)=>a+b,0)

ところでこういうのって何の役に立つの?

と思っている人多いでしょう。しかし、それは「1から2016まで」という数列に対して操作しているからそう思っているだけです。実際には「商品かごに入った商品の総額」や「レシートを読み取り、今月の支出を計算」、「1年間から土曜日曜、祝日、夏季休業、冬季休業を除いた平日日数のカウント」など本当に様々な場面で使います。「総和を取る」機能だけでもこれだけ使います。reduceは総和を取るだけではありませんし、filterはなければ破綻するほど使いますし、mapも相当使います。

というわけで全然無駄なんかではありません。これだけは強調しておきます。