Classificação da rotação da matriz

12

Vamos definir uma matriz não-vazia, não classificada e finita, com números exclusivos, como segue:

N={457136}

Vamos definir 4 movimentos de matriz como:

  • ↑ * (para cima): move uma coluna para cima
  • ↓ * (para baixo): move uma coluna para baixo
  • → * (direita): move uma linha para a direita
  • ← * (esquerda): move uma linha para a esquerda

O asterisco (*) representa a coluna / linha afetada pela movimentação (pode ser indexada em 0 ou indexada em 1. Depende de você. Indique qual em sua resposta).


O desafio é, usando os movimentos acima, classificar a matriz em uma ordem ascendente (sendo o canto superior esquerdo o mais baixo e o canto inferior direito o mais alto).

Exemplo

Entrada: Saída possível: ou . (Observe que qualquer um desses movimentos pode classificar a matriz para que ambas as respostas estejam corretas)

N={423156}
↑0↓0


Entrada: Saída possível:

N={231456}
→0


Entrada (exemplo de caso de teste): Saída possível:

N={457136}
↑0↑1←1↑2


Entrada: Saída possível:

N={596824173}
↑0↑2→0→2↑0→2↑1↑2←1


Entrada: Saída possível:

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


Entrada: Saída: ou qualquer movimento

N={1}


Entrada: Saída:

N={1234}


Notas

  • Pode haver diferentes saídas corretas (não precisa ser necessariamente o mesmo que os casos de teste ou o mais curto)
  • Você pode assumir que sempre será uma maneira de pedir a matriz
  • As arestas se conectam (como pacman: v)
  • Não haverá uma matriz com mais de 9 colunas ou / e linhas
  • Suponha que a matriz contenha apenas números inteiros positivos diferentes de zero
  • Você pode usar quaisquer quatro valores distintos, exceto números, para representar os movimentos (nesse caso, indique isso em sua resposta)
  • A coluna / linha pode ser indexada 0 ou 1
  • Critérios de vencimento

Casos de teste extras são sempre bem-vindos

Luis felipe De jesus Munoz
fonte
5
Aqui está um site onde você pode resolver esses quebra-cabeças.
Maçaneta
1
@ Doorknob Isso teria sido útil quando eu estava escrevendo o desafio Dx. Obrigado mesmo assim!
Luis felipe De jesus Munoz
Acho que você não diz em nenhum lugar que a solução dada deve ser a mais curta possível. Isso é intencional? Por exemplo, é ←0←0uma solução válida para o segundo exemplo em que você forneceu uma solução como →0. Se for, acho que metade das opções de movimentação provavelmente não serão usadas.
FryAmTheEggman
1
Além disso, algumas pessoas podem tentar o openprocessing.org/sketch/580366 feito por um youtuber chamado carykh. É chamado de "loopover"
Gareth Ma

Respostas:

3

JavaScript (ES6),  226  219 bytes

Pesquisa de força bruta, usando movimentos para a direita ( "R") e para baixo ( "D").

Retorna uma sequência que descreve as movimentações ou uma matriz vazia se a matriz de entrada já estiver classificada. As colunas e linhas na saída são indexadas em 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)

Experimente online!

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
Arnauld
fonte
Boa resposta. Você sabe se existe algo eficiente para isso ou se é possível determinar o número máximo de movimentos que uma solução pode ter sem força bruta?
Jonah
1
@Jonah Aqui está um artigo descrevendo uma solução e fornecendo um limite superior para o número de movimentos. (Veja também este desafio , que é basicamente a mesma tarefa com um critério vencedora diferente.)
Arnauld
Uau, obrigado @Arnauld #
Jonah
2

Python 2 , 296277245 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

Experimente online!

-19: flechas unicode não eram necessárias ...
-32: ligeiramente reformuladas, mas com desempenho muito mais lento em média.
-45: inspirou-se na resposta de @ Arnauld. Comutado para Python 3 para f''(-4 bytes)
-6: range( )r_[: ] , diff(ravel( ))ediff1d( )


Procura exaustivamente combinações de todos os movimentos possíveis e →0. Tempos limite no terceiro caso de teste.

Uma vez que →né equivalente a

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

onde re csão os números de linhas e colunas, esses movimentos são suficientes para encontrar todas as soluções.


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

>vcorrespondem respectivamente a →↓. (outros indefinidos)

attinat
fonte
0

Geléia , 35 bytes

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

Experimente online!

Programa completo. As saídas se movem para STDOUT usando L para a esquerda e R para a direita. Continua tentando movimentos aleatórios até a matriz ser classificada, portanto, não é muito eficiente em termos de velocidade ou complexidade algorítmica.

Nick Kennedy
fonte