행렬 회전 정렬


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 개 이상의 열 또는 행이있는 행렬이 없습니다.
  • 행렬에 0이 아닌 양의 정수만 포함한다고 가정
  • 숫자 이외의 4 가지 고유 한 값을 사용하여 이동을 나타낼 수 있습니다 (이 경우 답에 명시하십시오).
  • 열 / 행은 0 또는 1 색인화 될 수 있습니다.
  • 승리 기준

추가 테스트 케이스는 항상 환영합니다


5
다음은 이러한 퍼즐을 직접 해결할 수 있는 웹 사이트 입니다.
Doorknob

1
@Doorknob 도전 과제 Dx를 쓸 때 유용했을 것입니다. 어쨌든 고마워!
Luis felipe De jesus Munoz

주어진 솔루션이 가능한 한 짧아야한다고 말하는 곳은 없다고 생각합니다. 의도적인가요? 예를 들어 ←0←0솔루션을로 지정한 두 번째 예에 유효한 솔루션이 있습니다 →0. 그렇다면 이동 옵션의 절반이 사용되지 않을 것입니다.
FryAmTheEggman


1
또한 일부 사람들은 carykh라는 YouTube 사용자가 만든 openprocessing.org/sketch/580366 을 시도 할 수 있습니다 . 그것은 "루프 오버"라고 불린다
Gareth Ma

답변:


3

자바 스크립트 (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

좋은 대답입니다. 이를위한 효율적인 알고리즘이 존재하는지 또는 무차별 강제 실행없이 솔루션이 가질 수있는 최대 이동 수를 결정할 수 있는지 알고 있습니까?
Jonah

1
@Jonah 다음 은 해결책을 설명하고 이동 횟수의 상한을 제시하는 논문입니다. ( 승리 기준이 다른 기본적으로 동일한 과제이 과제 도 참조하십시오 .)
Arnauld

와, 감사합니다 @Arnauld
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 : range( )r_[: ] , diff(ravel( ))→ Python 3으로 전환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⁻Ṣ$$¿,“”Ṫ

온라인으로 사용해보십시오!

전체 프로그램. 왼쪽은 L, 오른쪽은 R을 사용하여 출력을 STDOUT으로 이동합니다. 행렬이 정렬 될 때까지 무작위 이동을 계속 시도하므로 속도 나 알고리즘 복잡성 측면에서 그다지 효율적이지 않습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.