1
$\begingroup$

I am trying to find a function $f(n) \to (x,y)$ that will take some number in the range $0 \dots (x \times y - 1)$ and give me the corresponding $(x,y)$.

The $(x,y)$ pattern that I want is as follows. If you imagine a grid on a page, with the top-left corner being $(0,0)$, then I want to fill in the page diagonally, left-to-right, bottom-to-top, starting from the upper-left corner.

So, in other words, I want to lay out my $n$'s like so:

$$ \begin{matrix} 0 & 2 & 5 \\ 1 & 4 & 7 \\ 3 & 6 & 8 \\ \end{matrix} $$

Corresponding to these $(x,y)$ co-ordinates:

$$ \begin{matrix} (0,0) & (1,0) & (2,0) \\ (0,1) & (1,1) & (2,1) \\ (0,2) & (1,2) & (2,2) \\ \end{matrix} $$

So, this mapping would be:

$$ f(0) \to (0,0) \\ f(1) \to (0,1) \\ f(2) \to (1,0) \\ f(3) \to (0,2) \\ f(4) \to (1,1) \\ f(5) \to (2,0) \\ \cdots $$

In code, I would express this with a for loop like so (grid of size $xs \times ys$, where $xs \ge ys$):

for (var v = 0, i = 0; v < xs+(ys-1); v++) {
    for (var x = Math.max(0, v-(ys-1)), y = Math.min(v, ys-1);
         y >= 0 && x < xs; x++, y--) {
        // f[i] == (x, y);
        i++;
    }
}

I've thought about using modulus, or dividing by some ratio or other trick, but I can't think of any obvious function that would map like this. But it does seem to me that such a thing should exist.

  • 0
    The diagonal part is what does my head in. I can find a function for left-to-right, top-to-bottom or vice-versa, but not diagonally.2017-01-22

1 Answers 1

1

Let $a=\min\{x,y\}$ and $b=\max\{x,y\}$.

The maximum length of a diagonal is limited by $a$, and there will be $1+(b-a)$ such diagonals. For each length $l\in\{1,2,\dots,a-1\}$ there will be two diagonals with length $l$, one before the diagonals of length $a$, and one afterwards. In other words, there are three 'sections':

$\,\,\,\,\,\,\,(\mathbf{1})$ Diagonals with increasing length, starting at $(0,0)$ with length $1$

$\,\,\,\,\,\,\,(\mathbf{2})$ Diagonals with maximum length ($a$), one after the other

$\,\,\,\,\,\,\,(\mathbf{3})$ Diagonals with decreasing length, like $(\mathbf{1})$ but after $(\mathbf{2})$


In $(\mathbf{1})$, a total of $1+2+\dots+(a-1)=\frac{a(a-1)}{2}$ points are crossed. Hence, if $0\leq n < \frac{a(a-1)}{2}$, then $f(n)$ lies in $(\mathbf{1})$. In this case, to which diagonal does it belong?

To answer this question, we must find the highest $m$ for which $1+2+\dots+m=\frac{m(m+1)}{2}\leq n$; then $n$ will be on the $(m+1)$-th diagonal. Rewriting the inequality yields:

$$m^2+m-2n\leq 0$$

so that

$$\frac{-1-\sqrt{1+8n}}{2}\leq m \leq \frac{-1+\sqrt{1+8n}}{2}$$

In particular, the highest $m$ is

$$d(n)=\left\lfloor\frac{-1+\sqrt{1+8n}}{2}\right\rfloor,$$

and $n$ belongs to the diagonal of length $d(n)+1$.

Now, each diagonal crosses points with constant coordinate sum. In $(\mathbf{1})$, the $(i+1)$-th diagonal crosses points whose coordinates sum to $i$, starting at $(0,i)$. At each step along the diagonal, the $x$ coordinate increases by $1$ and the $y$ coordinates decreases by $1$. Hence, we need only find how far along the diagonal $n$ is.

Since $1+2+\dots+d(n)=\frac12d(n)\big(d(n)+1\big)$ have been covered in previous diagonals, if we let

$$\Delta(n)=n-\frac12d(n)\big(d(n)+1\big),$$

then it follows that $f(n)=\Big(\Delta(n),d(n)-\Delta(n)\Big)$.


In $(\mathbf{2})$, a total of $a\cdot\big(1+(b-a)\big)=ab-a(a-1)$ points are crossed. Hence, if $\frac{a(a-1)}{2}\leq n

Each diagonal here has length $a$, so its easier to find the diagonal to which $n$ belongs. Let

$$\delta(n)=\left\lfloor\frac{n-\frac{a(a-1)}{2}}{a}\right\rfloor;$$

then $n$ belongs to the $\big(\delta(n)+1\big)$-th diagonal of $(\mathbf{2})$. How far along that diagonal $n$ is?

Well, $\frac{a(a-1)}{2}$ points have been crossed in $(\mathbf{1})$, and $\delta(n)$ diagonals have been crossed in $(\mathbf{2})$, for a total of $a\cdot\delta(n)$ points croosed in $(\mathbf{2})$, before $f(n)$. Therefore, if we let

$$\mathcal{D}(n)=n-\frac{a(a-1)}{2}-a\cdot\delta(n),$$

then it follows that $f(n)=\Big(\mathcal{D}(n),\delta(n)-\mathcal{D}(n)\Big)$.


The case where $f(n)$ lies in $(\mathbf{3})$ is handled similarly to when it lies in $(\mathbf{1})$. Notice that now diagonals start big (lenght $a-1$), getting smaller.

  • 0
    This is beautifully done. I love you approached the problem. I read the first 4 lines and then rushed off and excitedly tried to solve it for myself (which I did for the (2) case), haha. I guess it's been a long time since I've had to think mathematically like this, so thanks again for reminding me how it's done!2017-01-22
  • 0
    You're welcome! Glad to have helped. Notice this answer actually works only if you assume the rectangle has height $\geq$ width, so that diagonals always start at $(0,y)$, but the other case can be treated similarly.2017-01-23