Search code examples
c#asp.netdivide

Divide by 3, function in C#


I have a function that returns me list of int values depends on part of values:

private List<int> GetColumn(int total, int column)
{
    List<int> retList = new List<int>();

    if (total <= 0)
    {
        return retList;
    }

    if (column < 0 || column > 2)
    {
        column = 0;
    }

    int pageSize = total / 3;

    int startIndex = column * pageSize;
    int endIndex = column * pageSize + pageSize;

    if (endIndex > total)
    {
        endIndex = total;
    }

    for (int i = startIndex; i < endIndex; i++)
    {
        retList.Add(i);
    }

    return retList;

}

but it works wrong, because for: GetColumn(17, 0)

it returns [0,1,2,3,4], but should return [0,1,2,3,4,5]
for GetColumn(17, 1) - [6,7,8,9,10,11]
for GetColumn(17, 2) - [12,13,14,15,16]

for 16 it should return: for GetColumn(16, 0) - [0,1,2,3,4,5]
for GetColumn(16, 1) - [6,7,8,9,10]
for GetColumn(16, 2) - [11,12,13,14,15]

What should I change in my function? Thanks!


Solution

  • If this is what you need (numbers increase columnwise but rows need to be filled first):

    for 16:
    0  6  11
    1  7  12
    2  8  13
    3  9  14
    4  10 15
    5
    
    for 17:
    0  6  12
    1  7  13
    2  8  14
    3  9  15
    4  10 16
    5  11
    

    You need to define which column is getting the remainders:

    int remainder = total % 3;
    

    if remainder is 1, only first column is 6 elements. if remainder is 2, first & second columns are 6 elements. You need to calculate startIndex and endIndex according to this.

    So;

    int pageSize = total / 3;
    int remainder = total % 3;
    
    int startIndex = column * pageSize + min(column, remainder);
    int endIndex = startIndex + pageSize + (remainder > column ? 1 : 0);
    

    should work. I just tested it, it works for different rowsizes than 3.

    Here is how I got the formulas, drawing tables is good practice for sorting out such algortihms:

    r:Remainder, c:column, ps:pagesize (as calculated above)

    StartingIndex:
    .  |r:0 |r:1   |r:2
    ----------------------
    c:0|0   |0     |0
    ----------------------
    c:1|ps  |ps+1  |ps+1
    ----------------------
    c:2|ps*2|ps*2+1|ps*2+2
    

    You can see a pattern if you extend the table for rowsize 4:

    StartingIndex:
    .  |r:0 |r:1   |r:2   |r:3
    ------------------------------
    c:0|0   |0     |0     |0
    ------------------------------
    c:1|ps  |ps+1  |ps+1  |ps+1
    ------------------------------
    c:2|ps*2|ps*2+1|ps*2+2|ps*2+2
    ------------------------------
    c:3|ps*3|ps*3+1|ps*3+2|ps*3+3
    

    the value you are adding is the minimum of the related column and remainder

    Similarly for the endIndex, desired columns length can be seen when you build a table for given remainder vs column. I won't write that for now because it is taking too much time to draw the tables here and I believe you already got the idea.