格子点の生成
任意次元の格子点を(大量のメモリを使うことなく)生成するコードを出来るだけ汎用的に書いてみるテスト。
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"; } }
もうちょっと綺麗に書けそうな気がするけど、自分にはこのくらいが限界。リストを直接返すんじゃなくて、参照を返したほうが良いような気もするけどまあいいや。