マトリックス回転ソート


12

次のように、一意の番号を持つ空ではなく、並べ替えられていない有限行列を定義します

N={457136}

4つのマトリックスの動きを次のように定義します。

  • ↑*(上):列を上に移動します
  • ↓*(下):列を下に移動します
  • →*(右):行を右に移動します
  • ←*(左):行を左に移動します

アスタリスク(*)は、移動の影響を受ける列/行を表します(0インデックスまたは1インデックスにすることができます。あなた次第。答えの1つを明記してください)。


課題は、上記の動きを使用して、マトリックスを昇順でソートすることです(左上隅が最も低く、右下隅が最も高い)。

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}
出力:


ノート

  • 異なる正しい出力が存在する可能性があります(テストケースまたは最短のものと必ずしも同じである必要はありません)
  • あなたはそれが常に行列を注文する方法であると仮定することができます
  • エッジが接続する(pacman:vのように)
  • 9列以上の行列はありません
  • 行列には正の非ゼロの一意の整数のみが含まれていると仮定する
  • 数字以外の4つの異なる値を使用して移動を表すことができます(その場合は、答えにそれを明記してください)
  • 列/行には0または1のインデックスを付けることができます
  • 受賞基準

追加のテストケースはいつでも歓迎です


5
これらのパズルを自分で解決できるWebサイトを次に示します。
ドアノブ

1
@Doorknobこれは、チャレンジDxを書いていたときに役に立ちました。とにかくありがとう!
ルイスフェリペデイエスムニョス

与えられた解決策は可能な限り短くしなければならないということをどこにも言わないと思います。それは意図的ですか?たとえば、として←0←0ソリューションを指定した2番目の例の有効なソリューションです→0。もしそうなら、移動オプションの半分はおそらく使用されないと思います。
FryAmTheEggman


1
また、一部の人々は、carykhというyoutuberによって作成されたopenprocessing.org/sketch/580366を試してみたいかもしれません。「ループオーバー」と呼ばれる
ガレスMa

回答:


3

JavaScript(ES6)、 226  219バイト

"R")および"D")移動を使用したブルートフォース検索。

移動を説明する文字列、または入力行列が既にソートされている場合は空の配列を返します。出力の列と行には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)

オンラインでお試しください!

コメント済み

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

いい答え。このための効率的なアルゴリズムが存在するか、または総当たりなしでソリューションが持つことができる移動の最大数を決定できるかどうかを知っていますか?
ヨナ

1
@Jonah ここ紙溶液を記述し、移動の数の上限を与えることです。(このチャレンジも参照してください。これは、基本的に異なる勝利基準を持つ同じタスクです。)
アーナルド

わあ、ありがとう@アーナウルド
ヨナ

2

パイソン2、296 277 245 パイソン3 200の 194バイト

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

オンラインでお試しください!

-19:ユニコードの矢印は必要ありませんでした...
-32:わずかに手直しされましたが、平均してパフォーマンスが大幅に低下しました。
-45:@Arnauldの答えからインスピレーションを得ました。f''(-4バイト)
-6でPython 3に切り替え:range( )r_[: ]diff(ravel( ))ediff1d( )


すべての可能な動きとの組み合わせを徹底的に検索します→0。3番目のテストケースでタイムアウトします。

以来→nと同等です

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

ここでrおよびcは行と列の数であり、これらの動きはすべてのソリューションを見つけるのに十分です。


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

>vにそれぞれ対応し→↓ます。(その他は未定義)


0

ゼリー、35バイト

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

オンラインでお試しください!

完全なプログラム。Lは左、Rは右を使用して、出力がSTDOUTに移動します。行列が並べ替えられるまでランダムな移動を試行し続けるため、速度やアルゴリズムの複雑さの点であまり効率的ではありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.