In this task we want to find the ordered partitions into fixed-size blocks.

This task is related to Combinations in that it has to do with discrete mathematics and moreover a helper function to compute combinations is (probably) needed to solve this task.





p
a
r
t
i
t
i
o
n
s
(



a
r
g



1


,



a
r
g



2


,
.
.
.
,



a
r
g



n


)


{\displaystyle partitions({\mathit {arg}}_{1},{\mathit {arg}}_{2},...,{\mathit {arg}}_{n})}

 should generate all distributions of the elements in 



{
1
,
.
.
.
,

Σ

i
=
1


n





a
r
g



i


}


{\displaystyle \{1,...,\Sigma _{i=1}^{n}{\mathit {arg}}_{i}\}}

 into 



n


{\displaystyle n}

 blocks of respective size 






a
r
g



1


,



a
r
g



2


,
.
.
.
,



a
r
g



n




{\displaystyle {\mathit {arg}}_{1},{\mathit {arg}}_{2},...,{\mathit {arg}}_{n}}

.

Example 1: 



p
a
r
t
i
t
i
o
n
s
(
2
,
0
,
2
)


{\displaystyle partitions(2,0,2)}

 would create:

{({1, 2}, {}, {3, 4}), 
 ({1, 3}, {}, {2, 4}), 
 ({1, 4}, {}, {2, 3}), 
 ({2, 3}, {}, {1, 4}), 
 ({2, 4}, {}, {1, 3}), 
 ({3, 4}, {}, {1, 2})}

Example 2: 



p
a
r
t
i
t
i
o
n
s
(
1
,
1
,
1
)


{\displaystyle partitions(1,1,1)}

 would create:

{({1}, {2}, {3}), 
 ({1}, {3}, {2}), 
 ({2}, {1}, {3}), 
 ({2}, {3}, {1}), 
 ({3}, {1}, {2}), 
 ({3}, {2}, {1})}

Note that the number of elements in the list is








(






a
r
g



1


+



a
r
g



2


+
.
.
.
+



a
r
g



n






a
r
g



1




)



⋅



(






a
r
g



2


+



a
r
g



3


+
.
.
.
+



a
r
g



n






a
r
g



2




)



⋅
…
⋅



(





a
r
g



n





a
r
g



n




)





{\displaystyle {{\mathit {arg}}_{1}+{\mathit {arg}}_{2}+...+{\mathit {arg}}_{n} \choose {\mathit {arg}}_{1}}\cdot {{\mathit {arg}}_{2}+{\mathit {arg}}_{3}+...+{\mathit {arg}}_{n} \choose {\mathit {arg}}_{2}}\cdot \ldots \cdot {{\mathit {arg}}_{n} \choose {\mathit {arg}}_{n}}}


(see the definition of the binomial coefficient if you are not familiar with this notation) and the number of elements remains the same regardless of how the argument is permuted
(i.e. the multinomial coefficient).

Also, 



p
a
r
t
i
t
i
o
n
s
(
1
,
1
,
1
)


{\displaystyle partitions(1,1,1)}

 creates the permutations of 



{
1
,
2
,
3
}


{\displaystyle \{1,2,3\}}

 and thus there would be 



3
!
=
6


{\displaystyle 3!=6}

 elements in the list.

Note: Do not use functions that are not in the standard library of the programming language you use. Your file should be written so that it can be executed on the command line and by default outputs the result of 



p
a
r
t
i
t
i
o
n
s
(
2
,
0
,
2
)


{\displaystyle partitions(2,0,2)}

. If the programming language does not support polyvariadic functions pass a list as an argument.

Notation

Here are some explanatory remarks on the notation used in the task description:





{
1
,
…
,
n
}


{\displaystyle \{1,\ldots ,n\}}

 denotes the set of consecutive numbers from 



1


{\displaystyle 1}

 to 



n


{\displaystyle n}

, e.g. 



{
1
,
2
,
3
}


{\displaystyle \{1,2,3\}}

 if 



n
=
3


{\displaystyle n=3}

.





Σ


{\displaystyle \Sigma }

 is the mathematical notation for summation, e.g. 




Σ

i
=
1


3


i
=
6


{\displaystyle \Sigma _{i=1}^{3}i=6}

 (see also [1]).








a
r
g



1


,



a
r
g



2


,
.
.
.
,



a
r
g



n




{\displaystyle {\mathit {arg}}_{1},{\mathit {arg}}_{2},...,{\mathit {arg}}_{n}}

 are the arguments — natural numbers — that the sought function receives.




//*REXX program displays the  ordered partitions  as:   orderedPartitions(i, j, k, ···). */
call orderedPartitions  2,0,2                    /*Note:      2,,2      will also work. */
call orderedPartitions  1,1,1
call orderedPartitions  1,2,0,1                  /*Note:      1,2,,1    will also work. */
exit                                             /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
orderedPartitions: procedure;  #=arg();   bot.=;   top.=;   low=;    high=;    d=123456789
t=0                                              /*T:   is the sum of all the arguments.*/
          do i=1  for #;       t=t + arg(i)      /*sum all the highest numbers in parts.*/
          end   /*i*/                            /* [↑]  may have an omitted argument.  */
hdr= ' partitions for: '                         /*define the start of the header text. */
  do j=1  for #;               _= arg(j)         /*  _:  is the    Jth   argument.      */
  len.j=max(1, _)                                /*LEN:  length of args.  «0 is special»*/
  bot.j=left(d, _);         if _==0 then bot.j=0 /*define the  bottom  number for range.*/
  top.j=right(left(d,t),_); if _==0 then top.j=0 /*  "     "     top      "    "    "   */
  @.j=left(d, t);           if _==0 then   @.j=0 /*define the digits used for  VERIFY.  */
  hdr=hdr _                                      /*build (by appending)  display header.*/
  low=low || bot.j;         high=high || top.j   /*the low and high numbers for DO below*/
  end   /*j*/
                                                 /* [↓]  same as:   okD=left('0'd, t+1) */
              /*define the legal digits to be used.  */
okD=left(0 || d,  t + 1)                         /*define the legal digits to be used.  */
say;   hdr=center(hdr" ",  60, '═');     say hdr /*display centered title for the output*/
say                                              /*show a blank line  (as a separator). */
    do g=low  to high                            /* [↑]  generate the ordered partitions*/
    if verify(g, okD) \==0  then iterate         /*filter out unwanted partitions (digs)*/
    p=1                                          /*P:  is the position of a decimal dig.*/
    $=                                           /*$:  will be the transformed numbers. */
       do k=1  for #;   _=substr(g, p, len.k)    /*verify the partitions numbers.       */
       if verify(_, @.k) \==0  then iterate g    /*is the decimal digit not valid ?     */
       !=                                        /* [↓]  validate the decimal number.   */
       if @.k\==0  then do j=1  for length(_);     z=substr(_, j, 1)        /*get a dig.*/
                        if pos(z, $)\==0               then iterate g       /*previous ?*/
                        !=!','z                                             /*add comma.*/
                        if j==1                        then iterate         /*is firstt?*/
                        if z<=substr(_, j-1, 1)        then iterate g       /*ordered  ?*/
                        if pos(z, _, 1 +pos(z, _))\==0 then iterate g       /*duplicate?*/
                        end   /*j*/
       p=p + len.k                               /*point to the next decimal digit (num)*/
       $=$ '  {'strip(translate(!, ,0), ,",")'}' /*dress number up by suppessing LZ ··· */
       end   /*k*/
    say center($, length(hdr) )                  /*display numbers in ordered partition.*/
    end      /*g*/
return