M.Shiz
M.Shiz

Reputation: 85

Integer divisions of a number

How do I split a number into equal parts or as close to equal as possible. See example below:

If I have a value of 61 that i want to distribute between two groups, it would be 30.5 and 30.5. Doubles (decimals) are no good, so in this regard the closest split is 30 and 31.

Similarly 42 / 5 = 8.4, however I need the system to return (8, 8, 8, 9, 9) which is the closest split with whole numbers.

Solved it guys:

        if(sum % numberOfTeams != 0) {
        al.add(0, sNOT);
    for(int i = 0; i < numberOfTeams - 1;  i++) {
        int remover = sum - sNOT;
        if(remover % (sNOT + 1) == 0) {
            al.add(i+1, sNOT + 1);
        }else {
         al.add(i + 1, sNOT);

        }

     }
}

}

Upvotes: 5

Views: 211

Answers (4)

antonpuz
antonpuz

Reputation: 3316

Here is a solution which entirely uses Arrays, a little shorter with no loops. Validity check should also be applied as suggested above

    int value = 42;
    int groups = 5;

    int residue = value % groups;
    int[] res = new int[groups];
    int division = value / groups;
    Arrays.fill(res, 0, residue, division +1);
    Arrays.fill(res, residue, res.length, division);

    System.out.println(Arrays.toString(res));

Upvotes: 4

Taslim Oseni
Taslim Oseni

Reputation: 6263

The major thing you need to consider while solving this question is remainders.

From the example above, we intend to split 61 into 2, 61 / 2 gives a remainder of 1. Since we're splitting into two groups, only 1 out of these 2 groups have to be ((int) 61 / 2) + 1. The remaining (one) group can be ((int) 61 / 2).

Also, consider splitting 42 into 5, 42 / 5 gives a remainder of 2. Since, we're splitting into 5 groups, only 2 out of these 5 groups have to be ((int) 42 / 5) + 1. The remaining (three) groups can be ((int) 42 / 5).

Here's the code:

public int[] spitNumbers(int number, int groups){

    int[] result = new int[groups];  //The array we'd return at the end

    int shift = number % groups;  //I used this to check the remainder.

    for(int i = 0; i < result.length; i++){

    /* The if-statement below checks for two things:
       - if the remainder is zero
       - if we've reached the shifting stage.
    */
        if((shift == 0) || (i < shift)){
            result[i] = number / groups;
        }

    // The else statement starts being fired when the shifting stage has been reached.

        else{
            result[i] = (number / groups) + 1;
        }
    }
    return result;
}

I hope this helps.. Merry coding!

Upvotes: 1

ImZ
ImZ

Reputation: 46

Please have a look at this solution, I little tested, it works.

public static int[] number(int number, int divider) {
    if (number == 0 || number < divider) {
        return new int[]{0};
    }
    if (number == 1 || number == divider) {
        return new int[]{1};
    }
    double r = (double) number / divider;
    int upperCount = number % divider;
    return IntStream.range(0, divider).map(i ->{
        if (i < upperCount) {
            return (int) Math.ceil(r);
        }
        return (int) Math.floor(r);
    }).toArray();
}

p.s. little simplfied

Upvotes: -1

Sweeper
Sweeper

Reputation: 270770

Here's one solution:

public static int[] closestSplit(int intToSplit, int noOfGroups) {

    int[] result = new int[noOfGroups];
    Arrays.fill(result, intToSplit / noOfGroups);
    for (int i = 0; i < intToSplit % noOfGroups; i++) {
        result[i]++;
    }
    return result;

}


// usage:
System.out.println(Arrays.toString(closestSplit(42, 5)));

Basically, it creates an array of length noOfGroups first, then fills that with the integer division of intToSplit and noOfGroups. Next, it adds one to the first intToSplit mod noOfGroups elements of the array.

If you require the result to be ordered in ascending order, you can loop from the end of the array or use Arrays.sort.

Upvotes: 3

Related Questions