June 2018 Update

This commit is contained in:
Ingy döt Net 2018-06-22 20:57:24 +00:00
parent ba8067c3b7
commit 22f33d4004
5278 changed files with 84726 additions and 14379 deletions

View file

@ -1,4 +1,6 @@
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.
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.
<math>partitions(\mathit{arg}_1,\mathit{arg}_2,...,\mathit{arg}_n)</math> should generate all distributions of the elements in <math>\{1,...,\Sigma_{i=1}^n\mathit{arg}_i\}</math> into <math>n</math> blocks of respective size <math>\mathit{arg}_1,\mathit{arg}_2,...,\mathit{arg}_n</math>.
@ -27,7 +29,9 @@ Example 2: <math>partitions(1,1,1)</math> would create:
Note that the number of elements in the list is
:<math>{\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}</math>
(see [http://en.wikipedia.org/wiki/Binomial_coefficient 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 [http://en.wikipedia.org/wiki/Multinomial_coefficient multinomial coefficient]). Also, <math>partitions(1,1,1)</math> creates the permutations of <math>\{1,2,3\}</math> and thus there would be <math>3! = 6</math> elements in the list.
(i.e. the [http://en.wikipedia.org/wiki/Multinomial_coefficient multinomial coefficient]).
Also, <math>partitions(1,1,1)</math> creates the permutations of <math>\{1,2,3\}</math> and thus there would be <math>3! = 6</math> 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 <math>partitions(2,0,2)</math>. If the programming language does not support polyvariadic functions pass a list as an argument.
@ -35,4 +39,9 @@ Note: Do not use functions that are not in the standard library of the programmi
Here are some explanatory remarks on the notation used in the task description:
<math>\{1, \ldots, n\}</math> denotes the set of consecutive numbers from <math>1</math> to <math>n</math>, e.g. <math>\{1,2,3\}</math> if <math>n = 3</math>. <math>\Sigma</math> is the mathematical notation for summation, e.g. <math>\Sigma_{i=1}^3 i = 6</math> (see also [http://en.wikipedia.org/wiki/Summation#Capital-sigma_notation]). <math>\mathit{arg}_1,\mathit{arg}_2,...,\mathit{arg}_n</math> are the arguments — natural numbers — that the sought function receives.
<math>\{1, \ldots, n\}</math> denotes the set of consecutive numbers from <math>1</math> to <math>n</math>, e.g. <math>\{1,2,3\}</math> if <math>n = 3</math>.
<math>\Sigma</math> is the mathematical notation for summation, e.g. <math>\Sigma_{i=1}^3 i = 6</math> (see also [http://en.wikipedia.org/wiki/Summation#Capital-sigma_notation]).
<math>\mathit{arg}_1,\mathit{arg}_2,...,\mathit{arg}_n</math> are the arguments — natural numbers — that the sought function receives.
<br><br>

View file

@ -0,0 +1,57 @@
/*
Author: Kevin Bacon [haxifix (@gmail.com)]
Date: 2018-05-16
*/
#include <iostream>
#include <algorithm>
#include <vector>
#include <numeric>
void partitions(std::vector<size_t> args) {
size_t sum = std::accumulate(std::begin(args), std::end(args), 0);
std::vector<size_t> nums(sum);
std::iota(std::begin(nums), std::end(nums), 1);
do {
size_t total_index = 0;
std::vector<std::vector<size_t>> parts;
for (const auto& a : args) {
std::vector<size_t> part;
bool cont = true;
for (size_t j = 0; j < a; ++j) {
for (const auto& p : part) {
if (nums[total_index] < p) {
cont = false;
break;
}
}
if (cont) {
part.push_back(nums[total_index]);
++total_index;
}
}
if (part.size() != a) {
break;
}
parts.push_back(part);
}
if (parts.size() == args.size()) {
std::cout << "(";
for (const auto& p : parts) {
std::cout << "{ ";
for (const auto& e : p) {
std::cout << e << " ";
}
std::cout << "},";
}
std::cout << ")," << std::endl;
}
} while (std::next_permutation(std::begin(nums), std::end(nums)));
}
int main() {
std::vector<size_t> args = { 2, 0, 2 };
partitions(args);
std::cin.ignore();
std::cin.get();
return 0;
}

View file

@ -0,0 +1,24 @@
using Combinatorics
function masked(mask, lis)
combos = []
idx = 1
for step in mask
if(step < 1)
push!(combos, Array{Int,1}[])
else
push!(combos, sort(lis[idx:idx+step-1]))
idx += step
end
end
Array{Array{Int, 1}, 1}(combos)
end
function orderedpartitions(mask)
tostring(masklis) = replace("$masklis", r"Array{Int\d?\d?,1}|Int\d?\d?", "")
join([tostring(lis) for lis in unique([masked(mask, p)
for p in permutations(1:sum(mask))])], "\n")
end
println(orderedpartitions([2, 0, 2]))
println(orderedpartitions([1, 1, 1]))

View file

@ -1,10 +1,15 @@
sub partition(@mask is copy) {
my $last = [+] @mask or return [[] xx @mask];
sort gather for @mask.kv -> $k,$v {
my @op;
my $last = [+] @mask or return [] xx 1;
for @mask.kv -> $k, $v {
next unless $v;
temp @mask[$k] -= 1;
for partition @mask { .take.[$k].push($last) }
for partition @mask -> @p {
@p[$k].push: $last;
@op.push: @p;
}
}
return @op;
}
.perl.say for partition [2,0,2];
.say for reverse partition [2,0,2];

View file

@ -1,46 +1,44 @@
/*REXX program displays ordered partitions: orderedPartitions(i, j, k, ···). */
//*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. */
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(); hdr=; bot.=; top.=; low=; high=; d=123456789
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. */
/* [↓] process each of the arguments. */
do j=1 for #; _=arg(j) /* _: is the Jth argument. */
len.j=max(1, _) /*LEN: length of args, 0=special. */
bot.j=left(d, _); if _==0 then bot.j=0 /*define the bottom number. */
top.j=right(left(d,t),_); if _==0 then top.j=0 /* " " top " */
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*/
okD=left(0 || d, t+1) /*define the legal digits to be used. */
say center(' partitions for: ' hdr" ", 60, '') /*display centered title for the output*/
say
/* [↓] 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 decimal digits. */
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 # /*verify the partitions numbers. */
/*validate number: dups/ordered/repeats*/
_=substr(g,p,len.k) /*ordered partition number to be tested*/
if verify(_, @.k)\==0 then iterate g /*is the decimal digit not valid ? */
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)
if pos(z, $)\==0 then iterate g /*previous. */
!=!','z
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.*/
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 number. */
$=$ ' {'strip( translate(!, ,0), ,",")'}' /*dress number up by suppressing LZ ···*/
p=p + len.k /*point to the next decimal digit (num)*/
$=$ ' {'strip(translate(!, ,0), ,",")'}' /*dress number up by suppessing LZ ··· */
end /*k*/
say ' ' $ /*display numbers in ordered partition.*/
say center($, length(hdr) ) /*display numbers in ordered partition.*/
end /*g*/
say
return