Search code examples
c#logic

Calculate new indexes when shifting a column in a table


enter image description here

The following example scenario:

I have the column A with
RowIndex: 4
ColumnIndex: 7

I want to shift the Column A 11 places to the left so my resulting column indexes (B) are
RowIndex: 2
ColumnIndex: 6

To make matters worse, the table is a sub-table and therefore does not start at index 0, 0 but something like 4, 2 as in this example is possible

I am pretty sure that this can be solved via modulo calculation but my brain refuses to give me the correct formula.

I started in c# so far with this coding but this doesnt seem to be right obviously (https://dotnetfiddle.net/5iEqgD):

public static void Main()
{
    int minColumnIndex = 4;
    int maxColumnIndex = 8;
    int minRowIndex = 2;
    int maxRowIndex = 5;

    int cellARowIndex = 4;
    int cellAColumnIndex = 7;

    int shiftCellToTheLeft = 11;

    int cellBColumnIndex = cellAColumnIndex - ((maxColumnIndex - minColumnIndex + 1) % shiftCellToTheLeft);
    int cellBRowIndex = cellARowIndex - ((maxColumnIndex - maxColumnIndex + 1) % shiftCellToTheLeft);

    Console.WriteLine("cellBColumnIndex: " + cellBColumnIndex);
    Console.WriteLine("cellBRowIndex: " + cellBRowIndex);

    // Result:
    // cellBColumnIndex: 2
    // cellBRowIndex: 3
}

What am I doing wrong here?


Solution

  • It will be easier if we divide the problem into 3 parts.

    1. Convert row / column index to table index.
    2. Subtract 11 from table index.
    3. Convert table index to row / column index.

    Reusable code:

    static class Table
    {
        private const int FirstRowIndex = 2;
        private const int FirstColumnIndex = 4;
        private const int ColumnCount = 5;
    
        public static int CellToTable(int row, int colum)
        {
            return (row - FirstRowIndex) * ColumnCount + colum - FirstColumnIndex;
        }
    
        public static (int row, int column) TableToCell(int index)
        {
            return (
                row: index / ColumnCount + FirstRowIndex,
                column: index % ColumnCount + FirstColumnIndex
            );
        }
    }
    

    I made the class static, but you can convert it, if you need several instances.

    It is easier if the ColumnCount is given instead of maxColumnIndex, because otherwise you have to calculate maxColumnIndex - minColumnIndex and then you are one off and have to add 1.

    Test:

    int tableIndex = Table.CellToTable(4, 7);
    Console.WriteLine("Table index = " + tableIndex);
    var (row, column) = Table.TableToCell(tableIndex);
    Console.WriteLine($"Row = {row}, Column = {column}");
    
    Console.WriteLine();
    Console.WriteLine("Subtract 11 from table index");
    tableIndex -= 11;
    
    Console.WriteLine("Table index = " + tableIndex);
    (row, column) = Table.TableToCell(tableIndex);
    Console.WriteLine($"Row = {row}, Column = {column}");
    Console.ReadKey();
    

    Prints:

    Table index = 13
    Row = 4, Column = 7
    
    Subtract 11 from table index
    Table index = 2
    Row = 2, Column = 6