Sortowanie rotacji macierzy

12

Pozwala zdefiniować niepustą, nieposortowaną i skończoną macierz z unikatowymi liczbami w następujący sposób:

N={457136}

Pozwala zdefiniować 4 ruchy macierzy jako:

  • ↑ * (w górę): Przesuwa kolumnę w górę
  • ↓ * (w dół): Przesuwa kolumnę w dół
  • → * (w prawo): Przesuwa rząd w prawo
  • ← * (po lewej): Przesuwa rząd w lewo

Gwiazdka (*) reprezentuje kolumnę / wiersz, na które ma wpływ ruch (może być indeksowany 0 lub indeksowany 1. Do Ciebie. Podaj, który z nich w odpowiedzi).


Wyzwaniem jest, używając powyższych ruchów, posortować macierz w porządku rosnącym (będąc lewym górnym rogiem najniższym i prawym dolnym rogiem najwyższym).

Przykład

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}


Notatki

  • Mogą istnieć różne prawidłowe dane wyjściowe (niekoniecznie muszą być takie same jak przypadki testowe lub najkrótsze)
  • Możesz założyć, że zawsze będzie to sposób na uporządkowanie matrycy
  • Krawędzie łączą się (jak pacman: v)
  • Nie będzie matrycy z więcej niż 9 kolumnami i / lub rzędami
  • Załóżmy, że macierz zawiera tylko dodatnie niezerowe liczby całkowite
  • Możesz użyć dowolnych 4 odrębnych wartości innych niż liczby do przedstawienia ruchów (w takim przypadku proszę podać to w odpowiedzi)
  • Kolumna / wiersz może być indeksowany 0 lub 1
  • Kryteria

Dodatkowe przypadki testowe są zawsze mile widziane

Luis Felipe De Jesus Munoz
źródło
5
Oto strona internetowa, na której możesz samodzielnie rozwiązać te zagadki.
Klamka
1
@Doorknob Przydałoby się, gdy pisałem wyzwanie Dx. W każdym razie dzięki!
Luis felipe De jesus Munoz
Nie sądzę, żebyś powiedział, że podane rozwiązanie musi być jak najkrótsze. Czy to celowe? Na przykład jest ←0←0poprawnym rozwiązaniem dla drugiego przykładu, w którym podano rozwiązanie jako →0. Jeśli tak, myślę, że połowa opcji ruchu prawdopodobnie nie zostanie użyta.
FryAmTheEggman
1
Również niektórzy ludzie mogą chcieć wypróbować openprocessing.org/sketch/580366 stworzony przez youtuber o nazwie carykh. Nazywa się to „loopover”
Gareth Ma

Odpowiedzi:

3

JavaScript (ES6),  226  219 bajtów

Wyszukiwanie z użyciem siły brutalnej za pomocą ruchów w prawo ( "R") i w dół ( "D").

Zwraca albo łańcuch opisujący ruchy, albo pustą tablicę, jeśli macierz wejściowa jest już posortowana. Kolumny i wiersze w danych wyjściowych mają indeks 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)

Wypróbuj online!

Skomentował

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
źródło
Niezła odpowiedź. Czy wiesz, czy istnieje do tego skuteczny algo, czy też możliwe jest określenie maksymalnej liczby ruchów, które rozwiązanie może wykonać bez brutalnego forsowania?
Jonasz
1
@Jonah Oto artykuł opisujący rozwiązanie i podający górną granicę liczby ruchów. (Zobacz także to wyzwanie, które jest w zasadzie tym samym zadaniem z innym kryterium wygranej.)
Arnauld
Wow, dziękuję @Arnauld
Jonah
2

Python 2 , 296 277 245 Python 3 , 200 194 bajtów

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

Wypróbuj online!

-19: strzały unicode nie były wymagane ...
-32: nieco przerobione, ale średnio znacznie wolniejsze działanie.
-45: czerpałem inspirację z odpowiedzi @ Arnauld. Przełączono na Python 3 dla f''(-4 bajtów)
-6: range( )r_[: ] , diff(ravel( ))ediff1d( )


Wyczerpująco wyszukuje kombinacje wszystkich możliwych ruchów i →0. Przekroczono limit czasu w trzecim przypadku testowym.

Ponieważ →njest to równoważne z

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

gdzie ri csą liczbami wierszy i kolumn, te ruchy są wystarczające, aby znaleźć każde rozwiązanie.


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

>vodpowiadają odpowiednio →↓. (inne niezdefiniowane)

attinat
źródło
0

Galaretka , 35 bajtów

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

Wypróbuj online!

Pełny program Wyjścia przesuwa się do STDOUT za pomocą L dla lewej i R dla prawej. Próbuje losowych ruchów, dopóki macierz nie zostanie posortowana, więc nie jest zbyt wydajna pod względem szybkości ani złożoności algorytmicznej.

Nick Kennedy
źródło