#!/usr/bin/perl -wl use strict; print for generate(4, [qw(a b c)], [qw(d e)], [qw(f g h)], ["i"], [qw(j k)], ["l"], ["m"]); sub generate { my $min = shift; my @non_empty = grep @$_, @_; return if $min > @non_empty; work($min, @non_empty); } sub work { my $min = shift; return "" if !@_; my $first = shift; return map { my $n = $_; length() < $min ? () : $_, map $_.$n, @$first; } work($min-1, @_); }