Mathematica, 63 55 bytes
f=If[#5<1,#+#4,f[#+#2,#3-1,#2,#5-1,#2-1-#4]]&;g=1~f~##&
Isso define uma função g
que pode ser chamada como
g[5, 5, 1, 3]
Estou usando uma abordagem recursiva. Ele usa até 2 (N + M) iterações, dependendo de quão baixo da espiral o resultado é encontrado. Ele lida com todas as entradas (até g[10^6,10^6,5^5-1,5^5]
, o que requer mais iterações) em alguns segundos, mas para entradas maiores, você precisará aumentar o limite de iteração padrão, como
$IterationLimit = 10000000;
Basicamente, se k
é o número inicial da espiral, estou verificando se o j
índice está 0
, nesse caso, posso apenas retornar k + i
. Caso contrário, jogo fora a linha superior, giro a espiral em 90 graus (no sentido anti-horário), incremento de k
acordo e olho a espiral restante. Podemos passar para a próxima espiral com o seguinte mapeamento de parâmetros:
- k n + 1 = k n + m n
- M n + 1 = N n - 1
- N n + 1 = M n
- i n + 1 = j n - 1
- j n + 1 = n m - i n - 1
Isso pressupõe que M é a largura e N é a altura.