0

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 :

  1. 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?

  2. 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.

Sean
  • 789
  • 6
  • 26
  • @FZs i mean, we can always chose to put at least one ball in one bucket. Then, if M > N, there would be buckets without any balls. In my example, the piegeons are the buckets, and the holes are the balls . I am assigning each bucket to at least one ball. – Sean Aug 19 '21 at 07:47
  • You no where clearly state the concrete inputs and the outputs to the algorithm (the `perm` func); one has to figure that out looking at your code. Please fix that. Your apparent input format has a huge flaw: N can only be up to 9. Is there a reason it should be a single string as opposed to an array of balls + an integer for the number of buckets? Are you trying to save memory? The format impacts the optimal algorithm. – Inigo Aug 19 '21 at 11:21
  • Sorry, not good enough. You can't say "The exact nature of the array seems unimportant." If I know 1-9 are the only possible balls, I will come up with an algorithm totally different than for an unbounded N. Also a sting vs array input involves parsing. And if you want to the algorithm for the abstract problem, why wouldn't the func be `perm(numBalls:number, numBuckets:number)`? Or if the ball IDs aren't contiguous, why not `perm(balls:Array, numBuckets:number)`? Is there something important about using strings? In other words, you can't have algorithm face-of with fuzzy specs. – Inigo Aug 19 '21 at 13:36
  • I used the string as a quick test. I did mention, that we can have ["1","2", ... "999", "|", "|"]. Does that not automatically imply, that the we can pass any array? The function is not doing anything string specific. That being said, i took string to use the "|" characters. – Sean Aug 19 '21 at 13:56
  • sorry, you didn't really read what i wrote. not many people are going to spend time on this if you're not willing to spend time to define on a clear, unambiguous and fixed input and output spec. Look at how challenges are posed on LeetCode. – Inigo Aug 19 '21 at 14:05
  • The stars and stripes problem uses `★★★★|★★|★` ONLY as a graphical representation, not as the expected literal output of the abstract problem. Not that it speaks of N-tuples, etc. – Inigo Aug 19 '21 at 14:13
  • @Inigo yes, that is correct. I quickly wanted to see the output. That is why i used the bars. – Sean Aug 19 '21 at 14:16

0 Answers0