-2

The Problem:

I have a matrix that has X number of columns and Y number of rows.

The tiles are labeled from left to right, top to bottom with numbers in ascending order one by one.

In a Pythonic, mathy way, how can I get the coordinates of an N number? How can I get an N number from the coordinates?


Example:

I have a matrix of columns(X) = 5 and row(y) = 6

So something like this:

+----+----+----+----+----+
| 1  | 2  | 3  | 4  | 5  |
+----+----+----+----+----+
|  6 |  7 |  8 |  9 | 10 |
+----+----+----+----+----+
| 11 | 12 | 13 | 14 | 15 |
+----+----+----+----+----+
| 16 | 17 | 18 | 19 | 20 |
+----+----+----+----+----+
| 21 | 22 | 23 | 24 | 25 |
+----+----+----+----+----+
| 26 | 27 | 28 | 29 | 30 |
+----+----+----+----+----+

Example code:

COLUMN_X = 5
ROW_Y = 6

def cord_to_n(column, row):
    # do the magic
    return n

def n_to_cord(n):
    # do the magic
    return column, row

The expected output:

>>> cord_to_n(2,4) # 2nd column, 4th row
17

>>> n_to_cord(23)
(3,5) # 3rd column, 5th row

Note:

I prefer a solution without using any library, but instead using python math operators.


EDIT

1) This is not my homework or anything, I am self-studying programming and my school does not offer computer science.

2) This was my attempt:

def magic(n):
    n = int(n)
    x = n % COLUMN_X # column number
    y = n/ROW_Y + 1 # row number
    return y,x

For a while I thought it worked but found out that if the number I am searching for is in the last column it does not work.

Reblochon Masque
  • 35,405
  • 10
  • 55
  • 80
Programer Beginner
  • 1,377
  • 6
  • 21
  • 47
  • 2
    Please add code of what you tried. This is pretty trivial and smells like homework. – Jan Christoph Terasa Aug 05 '18 at 11:23
  • @RoryDaulton Just edited. I already tried it. I also tried to google and this might be even a duplicate question but most likely due to using non-accurate keywords I could not find solution through google. – Programer Beginner Aug 05 '18 at 11:42
  • @ChristophTerasa This is not a homework as stated in my edit. I am self-studying Python so I rely mainly on free resources online and forum such as stackoverflow. – Programer Beginner Aug 05 '18 at 11:43
  • Hints: In your attempt, use integer division `//`, not float division `/`, to find `y`. One way to correct your calculation of `x` is to do a conditional: what if the number is in the last column, how can you correct the calculation? Finally, your `return` statement was the values switched. – Rory Daulton Aug 05 '18 at 11:51
  • @RoryDaulton Does using `//` instead of `/` change anything? As for the return, I know it is switched. I wanted the row first and then the column. As for your suggestion using conditional, I already thought of that, using `if x == 0: x=5` but I thought there would be more 'nicer' way of solving it therefore I put a note there saying: "using python math operators". – Programer Beginner Aug 05 '18 at 11:57
  • It can be done with only operators by applying a simple fix, but why do you *want* a nicer solution? – meowgoesthedog Aug 05 '18 at 12:03
  • 1
    In Python 3, `/` gives a non-integer result, but if you are using Python 2 then `/` works. Another way to find `x` is to do operations on `x-1` then adjust the result. Yet another way is to use [the ternary `if` operator](https://stackoverflow.com/a/394814/6246044), which is closer to my earlier hint. There are multiple ways to do this--you choose which is best for your situation. I chose my hint to be the one closest to what you had already tried. – Rory Daulton Aug 05 '18 at 12:05
  • Oops, in my previous comment I meant "do operations on `n-1`..." – Rory Daulton Aug 05 '18 at 12:22

1 Answers1

0

The following small helper will translate every index from your matrix, to its row-col coordinates (based at zero, like python)

[Edit] -> If you want the row and col indices starting at one, you can do as follows:

row, col = convert_to_base1(get_row_col(idx, rows, cols))

following is the code and tests:

def convert_to_base1(args):
    row, col = args
    return row + 1, col + 1

def get_row_col(idx, rows, cols):
    """ translates a provided index to its row col coordinates

    idx: int, the index to translate
    rows: int, the number of rows
    cols: int, the number of columns
    """
    ndx = idx - 1
    row = ndx // cols
    col = ndx % cols
    return row, col

def test_get_row_col():
    assert get_row_col(22, 6, 5) == (4, 1)
    assert get_row_col(5, 6, 5) == (0, 4)
    assert get_row_col(6, 6, 5) == (1, 0)
    assert get_row_col(10, 6, 5) == (1, 4)
    assert get_row_col(1, 6, 5) == (0, 0)
    assert get_row_col(11, 6, 5) == (2, 0)
    assert get_row_col(13, 6, 5) == (2, 2)
    assert get_row_col(30, 6, 5) == (5, 4)
    assert get_row_col(26, 6, 5) == (5, 0)

    assert get_row_col(26, 1, 30) == (0, 25)
    assert get_row_col(26, 10, 10) == (2, 5)
    assert get_row_col(26, 7, 4) == (6, 1)
    assert get_row_col(26, 4, 7) == (3, 4)
    print('***all test_get_row_col pass***')

def test_get_row_col_convert_to_base1():
    assert convert_to_base1(get_row_col(22, 6, 5)) == (5, 2)
    assert convert_to_base1(get_row_col(5, 6, 5)) == (1, 5)
    assert convert_to_base1(get_row_col(6, 6, 5)) == (2, 1)
    assert convert_to_base1(get_row_col(10, 6, 5)) == (2, 5)
    assert convert_to_base1(get_row_col(1, 6, 5)) == (1, 1)
    assert convert_to_base1(get_row_col(11, 6, 5)) == (3, 1)
    assert convert_to_base1(get_row_col(13, 6, 5)) == (3, 3)
    assert convert_to_base1(get_row_col(30, 6, 5)) == (6, 5)
    assert convert_to_base1(get_row_col(26, 6, 5)) == (6, 1)

    assert convert_to_base1(get_row_col(26, 1, 30)) == (1, 26)
    assert convert_to_base1(get_row_col(26, 10, 10)) == (3, 6)
    assert convert_to_base1(get_row_col(26, 7, 4)) == (7, 2)
    assert convert_to_base1(get_row_col(26, 4, 7)) == (4, 5)
    print('***all test_get_row_col_convert_to_base1 pass***')


test_get_row_col()
test_get_row_col_convert_to_base1()
Reblochon Masque
  • 35,405
  • 10
  • 55
  • 80