Orden de rotación de matriz


12

Vamos a definir una matriz no vacía, sin clasificar y finita con números únicos de la siguiente manera:

N={457136}

Vamos a definir 4 movimientos de matriz como:

  • ↑ * (arriba): Mueve una columna hacia arriba
  • ↓ * (abajo): mueve una columna hacia abajo
  • → * (derecha): mueve una fila a la derecha
  • ← * (izquierda): mueve una fila a la izquierda

El asterisco (*) representa la columna / fila que se ve afectada por el movimiento (puede estar indexado 0 o indexado. Depende de usted. Indique cuál en su respuesta).


El desafío es, usando los movimientos anteriores, ordenar la matriz en orden ascendente (siendo la esquina superior izquierda la más baja y la esquina inferior derecha la más alta).

Ejemplo

Entrada:

N={423156}
Salida posible: ↑0o ↓0. (Observe que cualquiera de esos movimientos puede ordenar la matriz para que ambas respuestas sean correctas)


Entrada:

N={231456}
Salida posible:→0


Entrada (Ejemplo de caso de prueba):

N={457136}
Salida posible:↑0↑1←1↑2


Entrada:

N={596824173}
Salida posible: ↑0↑2→0→2↑0→2↑1↑2←1


N={127282961023451778139151112181426162119203022232425}
↑2↑1←3→0←3↓0←0←2→3↑3↑4


N={1}


N={1234}


Notas

  • Puede haber diferentes resultados correctos (no es necesario que sean necesariamente los mismos que los casos de prueba o el más corto)
  • Puede suponer que siempre será una forma de ordenar la matriz
  • Bordes conecta (como pacman: v)
  • No habrá una matriz con más de 9 columnas o filas
  • Suponga que la matriz contiene solo enteros únicos positivos distintos de cero
  • Puede usar 4 valores distintos que no sean números para representar los movimientos (en ese caso, indíquelo en su respuesta)
  • La columna / fila puede ser 0 o 1 indexada
  • Criterio ganador

Los casos de prueba adicionales siempre son bienvenidos


55
Aquí hay un sitio web donde puede resolver estos rompecabezas usted mismo.
— Pomo de la puerta

1
@Doorknob Eso hubiera sido útil cuando estaba escribiendo el desafío Dx. ¡Gracias de cualquier manera!
— Luis felipe De jesus Munoz

No creo que digas en ningún lado que la solución dada debe ser lo más breve posible. ¿Es eso intencional? Por ejemplo, es ←0←0una solución válida para el segundo ejemplo donde ha dado una solución como →0. Si es así, creo que la mitad de las opciones de movimiento probablemente no se utilizarán.
— FryAmTheEggman


1
También algunas personas pueden querer probar openprocessing.org/sketch/580366 hecho por un youtuber llamado carykh. Se llama "loopover"
— Gareth Ma

Respuestas:


3

JavaScript (ES6),  226  219 bytes

Búsqueda de fuerza bruta, utilizando movimientos hacia la derecha ( "R") y hacia abajo ( "D").

Devuelve una cadena que describe los movimientos o una matriz vacía si la matriz de entrada ya está ordenada. Las columnas y filas en la salida están indexadas a 0.

f=(m,M=2)=>(g=(s,m)=>m[S='some'](p=r=>r[S](x=>p>(p=x)))?!s[M]&&m[0][S]((_,x,a)=>g(s+'D'+x,m.map(([...r],y)=>(r[x]=(m[y+1]||a)[x])&&r)))|m[S]((_,y)=>g(s+'R'+y,m.map(([...r])=>y--?r:[r.pop(),...r]))):o=s)([],m)?o:f(m,M+2)

Pruébalo en línea!

Comentado

f =                              // f = main recursive function taking:
(m, M = 2) => (                  //   m[] = input matrix; M = maximum length of the solution
  g =                            // g = recursive solver taking:
  (s, m) =>                      //   s = solution, m[] = current matrix
    m[S = 'some'](p =            // we first test whether m[] is sorted
      r =>                       // by iterating on each row
        r[S](x =>                // and each column
          p > (p = x)            // and comparing each cell x with the previous cell p
        )                        //
    ) ?                          // if the matrix is not sorted:
      !s[M] &&                   //   if we haven't reached the maximum length:
      m[0][S]((_, x, a) =>       //     try all 'down' moves:
        g(                       //       do a recursive call:
          s + 'D' + x,           //         append the move to s
          m.map(([...r], y) =>   //         for each row r[] at position y:
            (r[x] =              //           rotate the column x by replacing r[x] with
              (m[y + 1] || a)[x] //           m[y + 1][x] or a[x] for the last row (a = m[0])
            ) && r               //           yield the updated row
      ))) |                      //
      m[S]((_, y) =>             //     try all 'right' moves:
        g(                       //       do a recursive call:
          s + 'R' + y,           //         append the move to s
          m.map(([...r]) =>      //         for each row:
            y-- ?                //           if this is not the row we're looking for:
              r                  //             leave it unchanged
            :                    //           else:
              [r.pop(), ...r]    //             rotate it to the right
      )))                        //
    :                            // else (the matrix is sorted):
      o = s                      //   store the solution in o
)([], m) ?                       // initial call to g(); if we have a solution:
  o                              //   return it
:                                // else:
  f(m, M + 2)                    //   try again with a larger maximum length

Buena respuesta. ¿Sabes si existe un algoritmo eficiente para esto, o si es posible determinar el número máximo de movimientos que una solución puede tener sin forzarlo?
— Jonás

1
@ Jonás Aquí hay un artículo que describe una solución y da un límite superior del número de movimientos. (Vea también este desafío, que es básicamente la misma tarea con un criterio ganador diferente.)
— Arnauld

Wow, gracias @Arnauld
— Jonah

2

Python 2 , 296 277 245 Python 3 , 200 194 bytes

from numpy import*
def f(p):
 s='';u=[]
 while any(ediff1d(p)<0):u+=[(copy(p),s+f'v{v}',f':,{v}')for v in r_[:shape(p)[1]]]+[(p,s+'>0',0)];p,s,i=u.pop(0);exec(f'p[{i}]=roll(p[{i}],1)')
 return s

Pruébalo en línea!

-19: no se necesitaban flechas unicode ...
-32: ligeramente reelaborado, pero un rendimiento mucho más lento en promedio.
-45: se inspiró en la respuesta de @ Arnauld. Cambió a Python 3 para f''(-4 bytes)
-6: range( )→r_[: ] , diff(ravel( ))→ediff1d( )


Busca exhaustivamente combinaciones de todos los ↓movimientos posibles y →0. Tiempos de espera en el tercer caso de prueba.

Como →nes equivalente a

↓0↓1...↓(c-1) 	... repeated r-n times
→0
↓0↓1...↓(c-1)	... repeated n times

donde ry cson los números de filas y columnas, estos movimientos son suficientes para encontrar todas las soluciones.


from numpy import*
def f(p):
    s=''                                    #s: sequence of moves, as string
    u=[]                                    #u: queue of states to check
    while any(ediff1d(p)<0):                #while p is not sorted
        u+=[(copy(p),s+f'v{v}',f':,{v}')    #add p,↓v to queue
            for v in r_[:shape(p)[1]]]      # for all 0<=v<#columns
        u+=[(p,s+'>0',0)]                   #add p,→0
        p,s,i=u.pop(0)                      #get the first item of queue
        exec(f'p[{i}]=roll(p[{i}],1)')      #transform it
    return s                                #return the moves taken

>vcorresponden respectivamente a →↓. (otros indefinidos)


0

Jalea , 35 bytes

ṙ€LXȮƊ¦1
ÇZÇZƊ⁾ULXȮOịØ.¤?F⁻Ṣ$$¿,“”Ṫ

Pruébalo en línea!

Programa completo Las salidas se mueven a STDOUT usando L para la izquierda y R para la derecha. Sigue intentando movimientos aleatorios hasta que se ordena la matriz, por lo que no es muy eficiente en términos de velocidad o complejidad algorítmica.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.