Búsqueda de secuencia numérica "caracol"

8

Te dan enteros Ny M, 1 <= N,M <= 10^6e índices iy j. Su trabajo es encontrar el número entero en la posición [i][j]. La secuencia se ve así (para N=M=5, i=1, j=3el resultado es 23):

 1  2  3  4  5
16 17 18 19  6
15 24 25 20  7
14 23 22 21  8
13 12 11 10  9

El código más corto gana. ¡Buena suerte!

usuario32839
fuente
Tan bien como esto.
Martin Ender
1
Es posible que desee aclarar si M es el ancho o la altura.
Martin Ender
@ MartinBüttner: Creo que N corresponde a iy M a j. Entonces solo necesita especificar, que el caracol comienza en i=j=0y continúa en j=0dirección.
M.Herzkamp
66
¿Nuestro código debe completarse en un tiempo razonable con una cantidad razonable de memoria para los límites dados? Definitivamente puedo escribir un código válido para esos parámetros, que solo genera la espiral y busca el valor, pero en realidad no tengo 4 TB de memoria por ahí.
Martin Ender

Respuestas:

6

Mathematica, 63 55 bytes

f=If[#5<1,#+#4,f[#+#2,#3-1,#2,#5-1,#2-1-#4]]&;g=1~f~##&

Esto define una función gque se puede llamar como

g[5, 5, 1, 3]

Estoy usando un enfoque recursivo. Utiliza hasta 2 iteraciones (N + M) , dependiendo de qué tan abajo de la espiral se encuentre el resultado. Maneja todas las entradas (hasta g[10^6,10^6,5^5-1,5^5], lo que requiere la mayoría de las iteraciones) en unos pocos segundos, pero para entradas más grandes, deberá aumentar el límite de iteración predeterminado como

$IterationLimit = 10000000;

Básicamente, si kes el número inicial de la espiral, estoy verificando si el jíndice es 0en cuyo caso puedo regresar k + i. De lo contrario, tiro la fila superior, gire la espiral 90 grados (en sentido antihorario), incremente en kconsecuencia y en su lugar mire la espiral restante. Podemos pasar a la siguiente espiral con la siguiente asignación 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

Esto supone que M es el ancho y N es la altura.

Martin Ender
fuente
51 bytes: If[#5<1,#+#4,#0[#+#2,#3-1,#2,#5-1,#2-1-#4]]&[1,##]&
LegionMammal978
3

Pyth, 25 bytes

D(GHYZ)R?+G(tHGtZt-GY)ZhY

Esto define una función (,. Ejemplo de uso:

D(GHYZ)R?+G(tHGtZt-GY)ZhY(5 5 1 3

impresiones 23.

Esto es algorítmicamente idéntico a la respuesta de Mathematica de Martin Büttner, aunque se desarrolló de forma independiente. Por lo que puedo decir, esa es la única buena manera de hacerlo.

Tenga en cuenta que Pyth no puede manejar el rango de entrada completo en mi máquina, desbordará la pila y morirá con un segfault en entradas grandes.

isaacg
fuente
1

Haskell, 44

z j i m n|j==0=i+1|0<1=z(n-i-1)(j-1)n(m-1)+n

esto usa el enfoque recursivo regular

orgulloso Haskeller
fuente