読者です 読者をやめる 読者になる 読者になる

Panda Noir

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

forもifも使わないプログラミング入門(終)

シリーズ物書ききったの初めてかも

forやif抜きでできないもの

最終回なので、forやifを使わないとできない(使った方がむしろわかりやすい)プログラムを紹介して締めたいと思います。まあプログラミングしていく上でfor使えないと話になりませんからね。

正方行列の積を計算する

数学で出てくる行列の積の計算、あれはさすがにfor、if抜きでは難しいです。

まずforとif使ったバージョン(a、bはn次正方行列で、例えばaの(i,j)成分をa[i-1][j-1]と書くとします。aの(1,1)成分ならa[0][0]という具合です)。

for (var i = 0; i < n; i++) {
    for(var j = 0; j < n; j++) {
        for (var k = 0; k < n; k++) {
            c[i][j] = a[i][k] + b[k][j];
        }
    }
}

これだけです。

次にforとifなし、つまり前回までのようなプログラム。

c = a.map((row, i) =>
  row.map((_, j) =>
    row.reduce((sum, a_ik, k) => sum + a_ik * b[k][j], 0)
  )
)

どうですか?これならむしろ前者の方がいいですよね?何をしているのかサッパリわかりません。この例のように、インデックス(添字)を活用しなければならないプログラムはforとifを使った方がすっきりと書けます。

今までの課題をforとifで解いてみる

今までの課題はこのような感じです。

  • 1と2を足してみよう
  • 1から10を足してみよう
  • 1から2016まで足してみよう
  • 1から2016までのうち、偶数のみを取り出して総和をとる
  • 1から2016までのうち完全数であるものを取りだしてみる
  • 1から2016までのうち素数であるものを列挙する
  • 1から2016までそれぞれを2乗してして総和を求める

1と2を足すのにforを使うのはさすがに過剰なので1から10を足すところから書きます。

1から10を足してみよう

let sum = 0;
for (let i = 1; i <= 10; i++) {
    sum += i;
}
console.log(sum);

1から2016まで足してみよう

let sum = 0;
for (let i = 1; i <= 2016; i++) {
    sum += i;
}
console.log(sum);

1から2016までのうち、偶数のみを取り出して総和をとる

let sum = 0;
for (let i = 1; i <= 2016; i++) {
    if (i % 2 === 0) sum += i;
}
// こうも書けます
// for (let i = 2; i <= 2016; i += 2) {
//     sum += i;
// }
console.log(sum);

1から2016までのうち完全数であるものを取りだしてみる

const result = [];
for (let i = 1, sum = 0; i <= 2016; i++) {
    for (let j = 1; j < i; j++) {
        if (i % j === 0) {
            sum += j;
        }
    }
    if (sum === i) result.push(i);
}
console.log(result);

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

const result = [];
for (let i = 2; i <= 2016; i++) {
    result.push(i);
    for (let j = 2; j <= i * i; j++) {
        if (i % j === 0) {
            result.pop();
            break;
        }
    }
}
console.log(result);

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

let sum = 0;
for (let i = 1; i <= 2016; i++) {
    sum += i * i;
}
console.log(sum);

終わりに

こうやって比較するとforで書く方が応用性は高いですよね。まあforの機能に意味を持たせて分割してコードを読みやすくするのが.mapやら.reduceやらの意味なので、for使えないまま.mapや.reduce使っていると応用力が付きません。