¡Estamos fuera de control, doctor!

11

El Doctor, al tratar de escapar de las fuerzas Dalek, decidió enviarlos en un giro viajando en varios bolsillos del espacio en un movimiento en espiral.

Dependiendo de la naturaleza del espacio-tiempo disponible, El Doctor necesita ingresar a la TARDIS para controlar la altura y el ancho de la sección del espacio y su punto de entrada con el cual comenzar la espiral.

La sección del espacio se puede imaginar como una cuadrícula h x w llena de enteros secuenciales de izquierda a derecha, de arriba a abajo, comenzando con 1.

La posición de inicio se proporciona como rc para la fila y la columna ... A partir de esto, el software de TARDIS necesita escupir la lista ordenada de enteros obtenida en espiral hacia afuera en sentido antihorario desde la fila r columna c , comenzando hacia arriba ...

Su tarea, como acompañante del Doctor, es programar la TARDIS para que tome cuatro números, en el formato height width row columny que determine qué sector de espacio necesita recorrer la TARDIS para que coincida con el movimiento en espiral que se describe a continuación ...

Entrada 1

5 5 3 3

(Cuadrícula de 5 x 5, comenzando en la posición 3,3)

Salida 1

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

Explicando la salida

Rejilla original ingrese la descripción de la imagen aquí

Espiral generada ingrese la descripción de la imagen aquí

Entrada 2

2 4 1 2

(2 x 4 cuadrícula comenzando en la posición 1,2)

Salida 2

2 1 5 6 7 3 8 4

Explicando la salida

Ligeramente diferente como la espiral ahora debe circular alrededor de la cuadrícula para generar la salida respectiva ...

Rejilla original ingrese la descripción de la imagen aquí

Espiral generada ingrese la descripción de la imagen aquí

Reglas:

  1. Este es el código de golf, por lo que la longitud más corta del código obtiene la aprobación.

  2. Los ejemplos anteriores deben usarse para probar su código. Si no proporciona la salida respectiva, hay algo mal ...

  3. En su respuesta se deben proporcionar versiones de código tanto en golf como en golf ...

¡Buena suerte!

WallyWest
fuente
Permítanme señalarle que dibuje.io donde uno puede hacer dibujos bastante razonables rápidamente (tiene una excelente legibilidad con su versión dibujada a mano ... solo que no veo ningún círculo rojo). Considere i.stack.imgur.com/xbLSA.png como un ejemplo de lo que podría hacerse. Tenga en cuenta que eso tiene el xml incrustado, por lo que si va a draw.io puede importar desde url.
Lo tendré en cuenta para mi próxima necesidad de un dibujo, @MichaelT, gracias ...
WallyWest
1
Publico una respuesta con una función que devuelve la matriz como salida. Es aceptable?
edc65
@ edc65 Mate, tú y yo volvemos aquí en CG, permitiré una función de S (h, w, r, c) o similar para esto ... :)
WallyWest

Respuestas:

3

JavaScript (ES6) 124 163 177

Editar De una forma totalmente diferente, no necesita una matriz para almacenar las celdas visitadas. Usando el hecho de que el lado de la espiral aumenta de 1 después de cada 2 vueltas.

// New way
f=(h,w,y,x)=>
  (e=>{
    for(o=[],d=i=t=l=0;l<w*h;i<t?i+=2:[i,d,e]=[1,-e,d,++t])
      o[l]=y*w-w+x,l+=x>0&x<=w&y>0&y<=h,x+=d,y-=e
  })(1)||o


// Golfed
g=(h,w,y,x)=>
  (g=>{
    for(e=n=0;n<h*w;)g[[n%w+1,-~(n/w)]]=++n;
    for(o=[g[[x,y]]],l=d=1;l<n;l+=!!(o[l]=g[[x+=d,y+=e]]))
      g[[x,y]]=0,
      g[[x+e,y-d]]!=0&&([d,e]=[e,-d])
  })([])||o



// Not golfed
u=(h,w,y,x)=>{
  var i,j,dx,dy,kx,ky,o,n,
    g={} // simulate a 2dimensional array using a hashtable with keys in the form 'x,y'

  for(n=i=0; i++<h;) // fill grid (probably better done in a single loop)
    for(j=0; j++<w;)
      g[[j,i]] = ++n;
  o=[g[[x,y]]] // starting point in output
  dx=1, dy=0 // start headed right
  
  for(; !o[w*h-1]; ) // loop until all w*h position are put in output
  {
    g[[x, y]] = 0 // mark current position to avoid reusing
    kx=dy, ky=-dx // try turning left
    if(g[[x+kx, y+ky]] != 0) // check if position marked
    { // found a valid position
      dx=kx, dy=ky // change direction
    }
    x+=dx, y+=dy // move
    k=g[[x, y]] // get current value
    if (k) o.push(k) // put in output list if not 'undefined' (outside grid)
  }
  return o
}

// TEST - In FireFox

out=x=>O.innerHTML+=x+'\n';
[
 [[5,5,3,3],'13 8 7 12 17 18 19 14 9 4 3 2 1 6 11 16 21 22 23 24 25 20 15 10 5'],
 [[2,4,1,2],'2 1 5 6 7 3 8 4']
].forEach(t=>out(t[0] + '\n Result: ' + f(...t[0])+'\n Check:  ' + t[1]))

test=()=>
{
  var r, i=I.value.match(/\d+/g), h=i[0]|0, w=i[1]|0, y=i[2]|0, x=i[3]|0
  if (y>h||x>w) r = 'Invalid input'
  else r = f(h,w,y,x)
  out(i+'\n Reault: ' +r)
}
<pre id=O></pre>
Your test:<input id=I><button onclick="test()">-></button>

edc65
fuente
¡Golf increíble! De 300 a 163 ... Me quito el sombrero ante ustedes ...
WallyWest
1
@WallyWest con ese comentario me empujas a hacerlo mejor. Thnx
edc65
¡Agradable! Mi solución de Python fue mucho más larga, pero pensé, está bien, usas un método mejor. Ahora usas lo mismo y es aún más corto ... Tengo algo de trabajo que hacer. :)
randomra
@randomra Me encantaría verlo ...
WallyWest
2

Pitón 3, 191

Probablemente no sea un gran puntaje, pero aquí va:

def f(b,a,d,c):
 p,r,l,s,h=c+1j*d,-1j,1,0,0
 for _ in [0]*((a+b)**2):x,y=p.real,p.imag;0<x<a+1and 0<y<b+1and print(int((y-1)*a+x),end=' ');p+=r;s=(s+1)%l;t=s==0;h=(h+t)%2;l+=h<t;r*=(-1j)**t 

Nos movemos a lo largo de la espiral aumentando la longitud del lado después de cada segundo giro. Si nuestra posición está dentro de la cuadrícula dada, imprimimos su número correspondiente.

Las variables son:

  • p es una posición compleja
  • x e y son coordenadas de posición
  • r es dirección
  • s es posición en el lado actual
  • l es la longitud del lado actual
  • h es la paridad del ordinal del lado actual
randomra
fuente