格子点の生成

任意次元の格子点を(大量のメモリを使うことなく)生成するコードを出来るだけ汎用的に書いてみるテスト。
Python ならかなり簡単に書ける。generator(コルーチン)万歳。

def mesh(*points):
    if len(points) == 1:
        for x in points[0]:
            yield [x]
    else:
        for point in mesh(*points[:-1]):
            for x in points[-1]:
                yield point + [x]

if __name__ == '__main__':
    for point in mesh(range(10), range(10), range(10)):
        print point

Perl ならこんな感じ?めんどい。

sub mesh_iterator {
    my @coords = @_;
    my @indices = map { 0 } @coords;

    my $carry_up = sub {
        my $i = 0;
        while ($i <= $#indices) {
            if ($indices[$i] < @{$coords[$i]} - 1) {
                $indices[$i]++;
                return 1;
            } else {
                $indices[$i++] = 0;
            }
        }
        return 0;
    };

    my $finished = 0;
    return sub {
        return if $finished;
        my @ret = map { $coords[$_]->[$indices[$_]] } 0..$#indices;
        $finished = 1 unless $carry_up->();
        return @ret;
    };
}

if ($0 == __FILE__) {
    my $iter = mesh_iterator(map { [0..9] } 0..2 );
    while (my @x = $iter->()) {
        print join("\t", @x), "\n";
    }
}

もうちょっと綺麗に書けそうな気がするけど、自分にはこのくらいが限界。リストを直接返すんじゃなくて、参照を返したほうが良いような気もするけどまあいいや。