denthijs has asked for the wisdom of the Perl Monks concerning the following question:

Hi, i've got this array: ('#','*',0..9),
i'm trying to create a simple loop that incrementally loops through it (aka bruteforce) but i keep ending up with too big amounts of code.
I'm pretty sure this must be possible in a oneliner or something.
But the shortest i came close with is 14 (!!!) lines of code, so embarassing i won't quote 'm here ;)
the result of the loop should be something like this: 0,1,2,3,4,5,6,7,8,9,#,*,01,02,03,04,05,06,07,08,..*324#6..... thnx!

Replies are listed 'Best First'.
Re: perlgolf - bruteforceing an array
by hv (Prior) on May 12, 2003 at 11:13 UTC

    I don't understand why your list doesn't include "00", so I've assumed it is an accidental omission:

    perl -wle '$_="n";{++$_;y/a/o/;($s=$_)=~y/o-z/0-9#*/;print$s;redo}'

    Hugo
      right , when i 'base12' it will ommit 0000* entries....
      and indeed it was accidental, this does look like it'll work, THNX!:)
Re: perlgolf - bruteforceing an array
by Chady (Priest) on May 12, 2003 at 11:03 UTC

    Borrowed from merlyn's Permutations and combinations

    print join ",", @$_ for combinations('#','*',0..9); sub combinations { return [] unless @_; my $first = shift; my @rest = combinations(@_); return @rest, map { [$first, @$_] } @rest; }
    or does it need to be sorted?
    He who asks will be a fool for five minutes, but he who doesn't ask will remain a fool for life.

    Chady | http://chady.net/
Re: perlgolf - bruteforceing an array
by Jaap (Curate) on May 12, 2003 at 11:01 UTC
    Here's a hint that might be helpful: think of the array ('#','*',0..9) as a base for a 12-digit system (duodecimal). Then in a loop like this:
    foreach my $decimal (1 .. 100000000) { ###convert $decimal to 12-base system }
Re: perlgolf - bruteforceing an array
by benn (Vicar) on May 12, 2003 at 11:21 UTC
    Not as 'nice' as either of the above, but simple, quick and sorted - a strolly one-or-two-over-par, and could probably lose a couple of lines somewhere, I think :)
    my @arr = my @results = ('#','*',0..9); print join("\n",@results); # 1st lot foreach (0..10) { my @results2; foreach my $m (@results) { push @results2, map {$m.$_} @arr; } @results = @results2; print join("\n",@results); # subsequent }
    Cheers,
    Ben.

    update...or just be completely blown away by Hugo++. Top, Sir!

Re: perlgolf - bruteforceing an array
by Skeeve (Parson) on May 12, 2003 at 11:22 UTC
    I'm wondering what you want to achieve! Do you want to get all possible combinations of 1-12 characters from your array stuffed into one array? So to give an example for 4 instead of 12 chars the resulting array should be this?
    0,1,2,3, 01,02,03,10,12,13,20,21,23,30,31,32, 012,013,021,023,031,032, 102,103,120,123,130,132, 201,203,210,213,230,231, 301,302,310,312,320,321, 0123,0132,0213,0231,0312,0321, 1023,1032,1203,1230,1302,1320, 2013,2032,2103,2130,2301,2310, 3012,3021,3102,3120,3201,3210
      i want to try all the possible combinations to form dtmf sequences, .. so 000001 should be tried aswell.
      I'm testing my homemade phonesystem. (if it isnt broke, hit it again;)
        here is an explained version that gives you all combinations of a given length:
        # you call it with the length, a refernce to your # character Array and a string thats already done sub combine { my($length,$chars,$ready)= @_; my($char); # First test whether or not we have to add chars if ($length) { # if so we iterate through the chars foreach $char (@$chars) { # and call combine # recursively by decrementing the # level and adding one char to # the chars we already have combine ($length-1, $chars, $ready.$char); } } else { # if there is nothing left to do, # we simply print the result. # we could also push it to a global # array for later processing print $ready,"\n"; } } # this is the first call @chars=qw(0 1 2 3 4 5 6 7 8 9 # *); combine (2, \@chars, '');
        HTH
        How long should the numbers be?