Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I had a look at the very first piece of code on the page you referred to:</p> <pre><code>sub c{my$n=-1+shift;$n?map{my$c=$_;map$c.$_,c($n,@_)}@_:@_} </code></pre> <p>I have spread it out a bit to make it more readable; also I have made some changes to it to make it clearer (see <code>combinations</code>):</p> <pre><code>#!/usr/bin/perl use strict; use warnings; sub c { my $n=-1+shift; $n ? map{ my $c = $_; map $c . $_ , c($n ,@_) } @_ : @_; } sub combinations { my $number = shift; # remove the first item from @_ my @chars = @_; # the remainder of @_ $number --; # decrement $number, so that you will eventually exit # from this recursive subroutine (once $number == 0) if ($number) { # true as long as $number != 0 and $number not undef my @result; foreach my $char (@chars) { my @intermediate_list = map { $char . $_ } combinations($number, @chars); push @result, @intermediate_list; } return @result; # the current concatenation result will be used for creation of # @intermediate_list in the 'subroutine instance' that called 'combinations' } else { return @chars; } } print join " ", combinations(2, "A", "B"); print "\n"; print join " ", c(2, "A", "B"); print "\n\n"; print join " ", combinations(3, "A", "B"); print "\n"; print join " ", c(3, "A", "B"); print "\n"; </code></pre> <p>Both versions work in the same way, and they produce exactly the same output:</p> <pre><code>AA AB BA BB AA AB BA BB AAA AAB ABA ABB BAA BAB BBA BBB AAA AAB ABA ABB BAA BAB BBA BBB </code></pre> <p>I included some comments in the code, but perhaps a lengthier explanation is in order!? Well, here's an example to illustrate how things work: let's say we've got two items, "A" and "B", and we want to get all possible combinations of 2 of these items. In that case, <code>$number</code> will initially be equal to 2 (as we want to get pairs), and <code>@chars</code> will be equal to <code>('A', 'B')</code>.</p> <p>The first time <code>combinations</code> is called, <code>$number</code> is decremented to 1, thus the <code>if</code> condition is met, and we enter the <code>foreach</code> loop. This first sets <code>$char</code> to 'A'. It then calls <code>combinations(1, ('A', 'B'))</code>. As <code>$number</code> always gets decremented when the subroutine is called, <code>$number</code> is 0 in this 'child subroutine', consequently the child simply returns ('A', 'B'). Thus:</p> <pre><code>@intermediate_list = map { $char . $_ } ('A', 'B'); # $char eq 'A' </code></pre> <p><code>map</code> then takes both 'A' and 'B' and concatenates each with 'A' ($char), thus <code>@intermediate_list</code> is ('AA', 'AB'). In the next round of the <code>foreach</code> loop, the same is done with <code>$char = B</code>, which sets <code>@intermediate_list</code> to ('BA', 'BB').</p> <p>In each round the contents of <code>@intermediate_list</code> are pushed into the result list, hence <code>@result</code> eventually contains all possible combinations.</p> <p>If you want to get triplets instead of pairs, you will obviously start with <code>$number = 3</code>, and <code>combinations</code> will be called three times. The second time it's called it will return <code>@result</code>, i.e. a pair-containing list. Each item from that list will be concatenated with each character of the initial character set.</p> <p>Okay, I hope this makes sense. Please ask in case something has not become clear.</p> <p><strong>EDIT</strong>: Please see ysth's comment below.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload