I have N
distinct balls , labeled 1,2,3,4,...,N
. I also have M
distinct buckets labeled I,II,III,IV,...,M
. It is given that M < N
, and thus we can always choose a distribution to make sure that every bucket has at least 1
ball.
I need to distribute the balls in the buckets, where the order matters. That is, if I put balls 1 and 2
in bucket I
, this will be a different distribution than 2 and 1
in (the same) bucket I
. Additionally, all buckets should actually hold at least 1
ball.
My attempt to solution starts at the Stars and Bars problem. However, Stars and bars problem does not consider the different orderings as distinct. I therefore found this stackoverflow question, and code :
function perm(xs) {
let ret = [];
for (let i = 0; i < xs.length; i = i + 1) {
let rest = perm(xs.slice(0, i).concat(xs.slice(i + 1)));
if(!rest.length) {
ret.push([xs[i]])
} else {
for(let j = 0; j < rest.length; j = j + 1) {
ret.push([xs[i]].concat(rest[j]))
}
}
}
return ret;
}
This does list all permutations, and thus considers the order.
But I need to make sure, that there is no buckets with a zero ball count.
So I modify the code :
function perm(xs) {
let ret = [];
for (let i = 0; i < xs.length; i = i + 1) {
let rest = perm(xs.slice(0, i).concat(xs.slice(i + 1)));
if(!rest.length) {
ret.push([xs[i]])
} else {
for(let j = 0; j < rest.length; j = j + 1) {
var t = [xs[i]].concat(rest[j])
ret.push(t)
}
}
}
return ret;
}
Now I call by perms("01234|||")
. Then i can do:
var cases = perm("01234|||");
let cases_cor = [];
for ( var i =0; i < cases.length; i++) {
var s = cases[i];
var t = s.join("");
if ( ! (t.includes ( "||")) && ! (t[0] == "|") && ! (t[t.length-1] == "|") ) {
cases_cor.push(s);
}
}
This will produce output like :
0|1|234
0|12|34
0|123|4
01|2|34
01|23|4
012|3|4
etc.
As per comment, i have taken 01234
as some test labels. One could also go with perm(["1","2", ... "999", "|", "|"])
etc. Then the outputs would be :
"1", "|" , "2", "3", "|", "4"
"1", "|" , "2", "|", "3", "4"
etc.
Further edit:
The perm
function could take a number array as well. But I am doing this in Javascript, so for quick test, I used a string array, where I can use "|"
as a bucket separator. That way I can quickly see a result.
To review : The number of balls are unbounded. They are not identified with consecutive labels - I have named them "1", "2", ...
because they need to be distinct. However, perm(["1","2", "3",... "999", "|", "|"])
and perm(["1","3", "2",... "999", "|", "|"])
should return the same results. This is because, while each id is distinct, the set of all IDs in both cases are the same.
I have not implemented the number of buckets as a number, because I followed the Stars and Bars problem, and it is developed around the concept of bucket separators. Nothing in theory is speaking against supplying the number of buckets as a number, as long as the output prints each permutation, with clearly marking which ball went to which bucket.
The code will reject all permutations that start with a bar ( = first bucket empty) or two consecutive bars ( = another bucket empty inbetween) or the last character a bar ( = last bucket empty).
This however is a brute force solution. Thus my questions are :
What is the fastest algorithm in javascript (Moderator, I am looking for the fastest possible algorithm. I am not looking for recommendations based on opinion. Fastest, as measured in milliseconds should be an objective measure) , resp, is there a in built function for this?
Does my algorithm consider all edge cases?
To re-iterate the specs :
- Input : Either an array of IDs of Balls and Bucket Separators, or an array or IDs, and a Number indicating the number of Buckets, with consecutive numbers being their IDs. That is, in the later approach, number of bucket = 4, means that the buckets are IDd as 1,2,3,4. I used the former approach in my attempt. It does not have to be that way. The array can be of numbers, utf charachters, and so on.
- Output : An array, where each element is a permutation, clearly showing to which bucket which ball went. In my case, this is a 2D array, with each row being a permutation, each element a ball ID; or a bucket separator. Of course the array type depends on the input.
Thank you.