Tri par rotation de matrice

12

Permet de définir une matrice non vide, non triée et finie avec des nombres uniques comme suit:

N={457136}

Permet de définir 4 mouvements de matrice comme:

  • ↑ * (haut): déplace une colonne vers le haut
  • ↓ * (bas): déplace une colonne vers le bas
  • → * (droite): Déplace une ligne vers la droite
  • ← * (gauche): Déplace une ligne vers la gauche

L'astérisque (*) représente la colonne / ligne affectée par le déplacement (elle peut être indexée 0 ou indexée. À vous de choisir. Veuillez indiquer laquelle dans votre réponse).


Le défi est, en utilisant les mouvements ci-dessus, de trier la matrice dans un ordre ascendant (le coin supérieur gauche étant le plus bas et le coin inférieur droit le plus élevé).

Exemple

N={423156}
↑0↓0


N={231456}
→0


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


N={596824173}
↑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}


Remarques

  • Il peut y avoir différentes sorties correctes (il n'est pas nécessaire qu'elles soient nécessairement les mêmes que les cas de test ou les plus courts)
  • Vous pouvez supposer que ce sera toujours un moyen de commander la matrice
  • Les bords se connectent (comme pacman: v)
  • Il n'y aura pas de matrice avec plus de 9 colonnes ou / et lignes
  • Supposons que la matrice ne contient que des entiers uniques positifs non nuls
  • Vous pouvez utiliser 4 valeurs distinctes autres que des nombres pour représenter les mouvements (dans ce cas, veuillez l'indiquer dans votre réponse)
  • La colonne / ligne peut être indexée 0 ou 1
  • Critères gagnants

Les cas de test supplémentaires sont toujours les bienvenus

Luis felipe De jesus Munoz
la source
5
Voici un site Web où vous pouvez résoudre ces énigmes vous-même.
Poignée de porte
1
@Doorknob Cela aurait été utile lorsque j'écrivais le défi Dx. Merci quand même!
Luis felipe De jesus Munoz
Je ne pense pas que vous disiez nulle part que la solution proposée doit être aussi courte que possible. Est-ce intentionnel? Par exemple, est ←0←0une solution valide pour le deuxième exemple où vous avez donné une solution en tant que →0. Si c'est le cas, je pense que la moitié des options de déplacement ne seront probablement pas utilisées.
FryAmTheEggman
1
Certaines personnes pourraient également vouloir essayer openprocessing.org/sketch/580366 réalisé par un youtuber appelé carykh. Il est appelé "bouclage"
Gareth Ma

Réponses:

3

JavaScript (ES6),  226  219 octets

Recherche de force brute, en utilisant les mouvements vers la droite ( "R") et vers le bas ( "D").

Renvoie soit une chaîne décrivant les déplacements, soit un tableau vide si la matrice d'entrée est déjà triée. Les colonnes et les lignes de la sortie sont indexées sur 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)

Essayez-le en ligne!

Commenté

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
la source
Bonne réponse. Savez-vous s'il existe un algo efficace pour cela, ou s'il est possible de déterminer le nombre maximum de mouvements qu'une solution peut avoir sans forcer brutalement?
Jonah
1
@Jonah Voici un article décrivant une solution et donnant une limite supérieure du nombre de mouvements. (Voir aussi ce défi qui est fondamentalement la même tâche avec un critère de victoire différent.)
Arnauld
Wow, merci @Arnauld
Jonah
2

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

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

Essayez-le en ligne!

-19: les flèches unicode n'étaient pas nécessaires ...
-32: légèrement retravaillées, mais performances beaucoup plus lentes en moyenne.
-45: s'est inspiré de la réponse de @ Arnauld. Passé à Python 3 pour f''(-4 octets)
-6: range( )r_[: ] , diff(ravel( ))ediff1d( )


Recherche de manière exhaustive les combinaisons de tous les mouvements possibles et →0. Expiration du troisième test élémentaire.

Étant donné que →nest équivalent à

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

ret où csont les nombres de lignes et de colonnes, ces mouvements sont suffisants pour trouver chaque solution.


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

>vcorrespondent respectivement à →↓. (autres non définis)

attinat
la source
0

Gelée , 35 octets

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

Essayez-le en ligne!

Programme complet. Les sorties se déplacent vers STDOUT en utilisant L pour gauche et R pour droite. Continue d'essayer des mouvements aléatoires jusqu'à ce que la matrice soit triée, donc pas très efficace en termes de vitesse ou de complexité algorithmique.

Nick Kennedy
la source