多重ループは再帰で書ける

多重forは再帰で書ける - merom686の日記
以前も書いたが、多重ループは再帰で書ける。なかなか使う機会がなかったけど、昨日AtCoderの過去問を解いていたときに使えそうだと思った(使わなかった)。
下のソースは、N以下のすべての正整数の素因数分解を順不同で出力する。N以下の素数の数だけfor文を回したいのだが、そんな多重forは書くのが面倒だし、Nが事前にわかっていない場合はそもそも書けない。そこで再帰を使って多重ループしている。
自分は昔、オセロのソフトを作ろうとして、普通は再帰を使うところなのに、多重forで深さ固定のミニマックス法を書いたことがある。それを思えば、多重ループが再帰で書けるのは当たり前だ。

#include <iostream>
#include <iomanip>
#include <functional>

int main() {
    const int N = 16;
    int p[] = { 2, 3, 5, 7, 11, 13 }; // N以下の素数
    int c[10][2] = {};

    std::function<void(int, int, int)> f = [&](int m, int k, int j) {
        if (j < 0) {
            std::cout << std::setw(3) << m << " = ";
            bool b = false;
            for (int i = k - 1; i >= 0; i--) {
                if (b) std::cout << " * "; else b = true;
                std::cout << p[c[i][0]];
                if (c[i][1] > 1) std::cout << "^" << c[i][1];
            }
            if (!b) std::cout << "1";
            std::cout << std::endl;
            return;
        }
        for (int i = 0;; i++) {
            c[k][0] = j;
            c[k][1] = i;
            f(m, k + (i != 0), j - 1);
            m *= p[j];
            if (m > N) break;
        }
    };
    f(1, 0, _countof(p) - 1);

    return 0;
}

/* 出力
  1 = 1
  2 = 2
  4 = 2^2
  8 = 2^3
 16 = 2^4
  3 = 3
  6 = 2 * 3
 12 = 2^2 * 3
  9 = 3^2
  5 = 5
 10 = 2 * 5
 15 = 3 * 5
  7 = 7
 14 = 2 * 7
 11 = 11
 13 = 13
*/