Tuve que resolver este problema exacto hace unos años. Yo no era capaz de llegar con mi propia solución, sino que corrió a través de esta maravillosa pieza de código que implica un uso inteligente y juicioso de map
junto con la recursividad:
#!/usr/bin/perl
print "permute:\n";
print "[", join(", ", @$_), "]\n" for permute([1,2,3], [4,5,6], [7,8,9]);
sub permute {
my $last = pop @_;
unless(@_) {
return map([$_], @$last);
}
return map {
my $left = $_;
map([@$left, $_], @$last)
}
permute(@_);
}
Sí, esto parece una locura, pero me permite ¡para explicar! La función se repetirá hasta que @_
esté vacío, en cuyo punto devuelve ([1], [2], [3])
(una lista de tres arreglos de matriz) al nivel anterior de recursión. En ese nivel, $last
es una referencia a una matriz que contiene [4, 5, 6]
.
El cuerpo del mapa exterior se ejecuta entonces tres veces con $_
conjunto a [1]
, entonces [2]
y finalmente [3]
. El mapa interno se ejecuta más de (4, 5, 6)
para cada iteración del mapa exterior y esto devuelve ([1, 4], [1, 5], [1, 6])
, ([2, 4], [2, 5], [2, 6])
y finalmente ([3, 4], [3, 5], [3, 6])
.
La última pero una llamada recursiva devuelve ([1, 4], [1, 5], [1, 6], [2, 4], [2, 5], [2, 6], [3, 4], [3, 5], [3, 6])
.
A continuación, se ejecuta ese resultado contra [7,8,9]
, que le da [1, 4, 7], [1, 4, 8], [1, 4, 9], [1, 5, 7], [1, 5, 8], [1, 5, 9], [1, 6, 7], [1, 6, 8], [1, 6, 9], [2, 4, 7], [2, 4, 8], [2, 4, 9], [2, 5, 7], [2, 5, 8], [2, 5, 9], [2, 6, 7], [2, 6, 8], [2, 6, 9], [3, 4, 7], [3, 4, 8], [3, 4, 9], [3, 5, 7], [3, 5, 8], [3, 5, 9], [3, 6, 7], [3, 6, 8], [3, 6, 9]
Recuerdo enviar una pregunta a perlmonks.org pedir a alguien que explicar esto a mí.
Puede adaptar fácilmente esta solución a su problema.
Este no es permutación - permutación es ordenamientos de un conjunto dado (por ejemplo, {a, b, c} -> (a, b, c), (a, c, b), (b, a, c), ...). – Cascabel
oh lo siento. No lo sabía ¿Son combinaciones? – user295033
En realidad, me acabo de dar cuenta de que este es un duplicado: ver http://stackoverflow.com/questions/1256036/in-perl-how-can-i-iterate-over-the-cartesian-product-of-multiple-sets –