Mathematica, 63 55 bytes
f=If[#5<1,#+#4,f[#+#2,#3-1,#2,#5-1,#2-1-#4]]&;g=1~f~##&
This defines a function g
which can be called like
g[5, 5, 1, 3]
I'm using a recursive approach. It uses up to 2(N+M) iterations, depending on how far down the spiral the result is found. It does handle all inputs (up to g[10^6,10^6,5^5-1,5^5]
, which requires the most iterations) within a few seconds, but for larger inputs, you'll need to increase the default iteration limit like
$IterationLimit = 10000000;
Basically, if k
is the starting number of the spiral, I'm checking if the j
index is 0
in which case I can just return k + i
. Otherwise, I throw away the top row, rotate the spiral by 90 degrees (anti-clockwise), increment k
accordingly, and look at the remaining spiral instead. We can move to the next spiral with the following mapping of parameters:
- kn+1 = kn + mn
- Mn+1 = Nn - 1
- Nn+1 = Mn
- in+1 = jn - 1
- jn+1 = nm - in - 1
This assumes that M is the width and N is the height.
i=j=0
and continues inj=0
direction. \$\endgroup\$ – M.Herzkamp Nov 17 '14 at 13:00