矩阵旋转排序


12

让我们定义一个具有唯一数字的非空,未排序和有限矩阵,如下所示:

N={457136}

让我们定义4个矩阵移动为:

  • ↑*(向上):向上移动一列
  • ↓*(向下):向下移动一列
  • →*(右):向右移动一行
  • ←*(左):向左移动一行

星号(*)表示受移动影响的列/行(可以是0索引或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
这是一个您可以自己解决这些难题的网站
门把手

1
@Doorknob当我编写挑战Dx时,这将很有用。不管怎么说,还是要谢谢你!
路易斯·费利佩·德·耶稣·穆诺兹

我认为您在任何地方都不会说给出的解决方案必须尽可能短。那是故意的吗?例如←0←0,对于第二个示例,它是一个有效的解决方案,其中您给出的解决方案为→0。如果是这样,我认为可能不会使用一半的移动选项。
FryAmTheEggman


1
另外,有些人可能想尝试一下由称为carykh的youtuber制作的openprocessing.org/sketch/580366。它被称为“循环”
Gareth Ma

Answers:


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 是一篇描述解决方案并给出移动次数上限的论文。(另请参阅此挑战,基本上是相同的任务,但获胜标准却不同。)
Arnauld,

哇,谢谢@Arnauld
约拿(Jonah)

2

Python 2中,296 277 245 Python 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:不需要unicode箭头...
-32:略作修改,但平均而言性能要慢得多。
-45:从@Arnauld的答案中得到一些启发。切换至Python 3 f''(-4字节)
-6:range( )r_[: ]diff(ravel( ))ediff1d( )


穷举搜索所有可能的动作和组合→0。在第三个测试用例上超时。

因为→n等于

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

其中,rc是行数和列数,这些举动都足以找到每一个解决方案。


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⁻Ṣ$$¿,“”Ṫ

在线尝试!

完整程序。输出移至STDOUT,左为L,右为R。一直尝试随机移动,直到对矩阵排序为止,因此在速度或算法复杂性方面效率不高。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.