모든 사각형을 폭발 시키십시오


20

제곱 숫자 포함하는 너비 의 제곱 행렬이 제공 됩니다.21

당신의 임무는 모든 사각형 숫자가 모두 사라질 때까지 '폭발'하는 것입니다. 최종 행렬을 인쇄하거나 반환해야합니다.

더 구체적으로:

  1. 행렬에서 가장 높은 제곱 를 찾으십시오 .x2
  2. 인접한 가장 작은 인접 찾으십시오 (수평 또는 수직으로 감싸지 않은 상태).n
  3. 교체 와 및 대체 과 .x2xnn×x

행렬에 더 이상 사각형이 없을 때까지 1 단계부터 과정을 반복합니다.

입력 매트릭스 :

(62536196324)

최고 제곱 의 두 부분으로 폭발 및 작은 이웃과 병합 가되고, :625625=253636×25=900

(25900196324)

의 가장 높은 광장은 폭발하여 가장 작은 이웃 와 합쳐집니다 :90025

(75030196324)

가장 높은 광장 는 가장 작은 이웃 과 함께 폭발하고 합쳐집니다 .32430

(75054019618)

남아있는 유일한 광장 폭발하여 가장 작은 이웃 과 합쳐집니다 .19618

(75054014252)

더 이상 사각형이 없으므로 완료되었습니다.

규칙

  • 입력 행렬이되어 보장 다음과 같은 속성을 가지고 :
    • 각 단계에서 가장 높은 사각형은 항상 고유합니다.
    • 각 단계에서 가장 높은 사각형의 가장 작은 이웃은 항상 고유합니다.
    • 시퀀스는 영원히 반복되지 않습니다
  • 초기 행렬에는 이 포함될 수 있지만 분해 하는 것에 대해 걱정할 필요 가 없습니다.11
  • I / O는 합리적인 형식으로 처리 될 수 있습니다
  • 이것은

테스트 사례

Input : [[16,9],[4,25]]
Output: [[24,6],[20,5]]

Input : [[9,4],[1,25]]
Output: [[3,12],[5,5]]

Input : [[625,36],[196,324]]
Output: [[750,540],[14,252]]

Input : [[1,9,49],[1,4,1],[36,25,1]]
Output: [[3,6,7],[6,2,7],[6,5,5]]

Input : [[81,4,64],[16,361,64],[169,289,400]]
Output: [[3,5472,8],[624,323,1280],[13,17,20]]

Input : [[36,100,1],[49,144,256],[25,49,81]]
Output: [[6,80,2],[42,120,192],[175,21,189]]

Input : [[256,169,9,225],[36,121,144,81],[9,121,9,36],[400,361,100,9]]
Output: [[384,13,135,15],[24,1573,108,54],[180,11,108,6],[380,209,10,90]]

Input : [[9,361,784,144,484],[121,441,625,49,25],[256,100,36,81,529],[49,4,64,324,16],[25,1,841,196,9]]
Output: [[171,19,700,4032,22],[11,210,525,7,550],[176,60,6,63,23],[140,112,1152,162,368],[5,29,29,14,126]]

3
You must print or return the final matrix.대신 입력 행렬을 수정할 수 있습니까?
무지의 구현

2
@ 무지의 예 예, 완벽합니다.
Arnauld

코너 (대각선)의 값은 이웃을 고려합니까?
Luis felipe De jesus Munoz

1
출력에 0의 (여러 행과 열)을 채울 수 있습니까?
로빈 라이더

1
0

답변:


5

R , 301 287 277 274 222 217 195 186 178 174 바이트

엔트리 매트릭스의 주변 요소를 제로 버퍼링하는 것을 포함하여 특별히 독창적 인 것은 없으며, 이전 버전 은 Robin이 개선했습니다.

function(x){w=which.max
if(any(s<-!x^.5%%1)){
y=cbind(NA,rbind(NA,x,NA),NA)
z=y[i]=y[i<-w(y*y%in%x[s])]^.5
m=i+c(r<--c(1,nrow(y)),-r)
y[j]=y[j<-m[w(-y[m])]]*z
x=p(y[r,r])}
x}

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

일련의 숫자를 항목으로 사용하여 함수 호출을 제거함으로써 Nick Kennedy는 이전에 다음과 같이 186 바이트 버전 의 알고리즘을 관리 했습니다 ( Robin의 -10 바이트 ).

w=which.max;`~`=cbind;x=scan();while(any(s<-!x^.5%%1)){y=NA~t(NA~matrix(x,n<-length(x)^.5)~NA)~NA;i=w(y*y%in%x[s]);=i+c(r<--c(1,n+2),-r);y[j]=y[j<-m[w(-y[m])]]*(y[i]=y[i]^.5);x=y[r,r]};x

(재귀) 함수의 정의와 다른 좋은 이득을 피하십시오.

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


1
바이트 카운트가 꺼져 있습니다. 어쨌든, 여기 196 바이트의 엄청나게 골프화 된 버전이 있습니다 : tio.run/…
Nick Kennedy

2
질문 주셔서 감사합니다. 일반적으로 누군가가 귀하의 답변에 대한 의견으로 더 짧은 버전을 게시하는 경우, 해당 정보를 사용하여 답변을 적용 할 수 있습니다. 그런 다음 '<number> 바이트를 저장해 주셔서 감사합니다. @ <user>에게 감사합니다!'라는 텍스트의 어딘가에 추가하는 것이 예의입니다. 또는 유사합니다. 귀하의 답변과 크게 다른 곳 이었지만 귀하의 답변을 얻은 경우 대신 귀하를 인정하는 별도의 답변을 게시했을 수 있습니다. 그러나 여기에서 내가 한 대부분의 작업은 약간의 조정입니다. 기본적인 방법은 당신의 것입니다.
Nick Kennedy

2

루비 , 140 135 바이트

플랫리스트를 입력으로 받아서 플랫리스트를 출력합니다.

->m{i=1;(i=m.index m.reject{|e|e**0.5%1>0}.max
m[i+[1,-1,l=m.size**0.5,-l].min_by{|j|i+j>=0&&m[i+j]||m.max}]*=m[i]**=0.5if i)while i;m}

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

설명:

->m{                                # Anonymous lambda
    i=1;                            # Initialize i for the while loop
        (                           # Start while loop

i=m.index                           # Get index at...
    m.reject{|e|          }         # Get all elements of m, except the ones with...
                e**0.5%1>0          # a square root with a fractional component
                           .max     # Get the largest of these

m[i+                                # Get item at...
    [1,-1,l=m.size**0.5,-l]         # Get possible neighbors (up, down, left, right)
        .min_by{|j|i+j>=0&&m[i+j]|| # Find the one with the minimum value at neighbor
                            m.max}  # If out of range, return matrix max so
                                    #   neighbor isn't chosen
    ]
    *=m[i]**=0.5                    # Max square becomes its square root, then multiply
                                    #   min neighbor by it

)while i                            # End while loop. Terminate when index is nil.
m}                                  # Return matrix.


2

펄 6 , 236 바이트

{my@k=.flat;my \n=$_;loop {my (\i,\j)=@k>>.sqrt.grep({$_+|0==$_},:kv).rotor(2).max(*[1]);last if 0>i;$/=((0,1),(0,-1),(1,0),(-1,0)).map({$!=i+n*.[0]+.[1];+$!,n>.[0]+i/n&.[1]+i%n>=0??@k[$!]!!Inf}).min(*[1]);@k[i,$0]=j,j*$1};@k.rotor(+n)}

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


1
213 바이트 . 루핑 메커니즘이 짧을 수도 있다는 의문이 있습니다 ... 또한 우리가 파이썬에 맞아서 화가 났기 때문에 다른 접근 방식이 필요합니다
Jo King

2

MATL , 49 48 바이트

`ttX^tt1\~*X>X>XJt?wy=(tt5M1Y6Z+*tXzX<=*Jq*+w}**

온라인으로 사용해보십시오! 또는 모든 테스트 사례를 확인하십시오 .

작동 원리

`           % Do...while
  tt        %   Duplicate twice. Takes a matrix as input (implicit) the first time
  X^        %   Square root of each matrix entry
  tt        %   Duplicate twice
  1\~       %   Modulo 1, negate. Gives true for integer numbers, false otherwise
  *         %   Multiply, element-wise. This changes non-integers into zero
  X>X>      %   Maximum of matrix. Gives maximum integer square root, or zero
  XJ        %   Copy into clipboard J
  t         %   Duplicate
  ?         %   If non-zero
    wy      %     Swap, duplicate from below. Moves the true-false matrix to top
    =       %     Equals, element-wise. This gives a matrix which is true at the
            %     position of the maximum that was previously identified, and
            %     false otherwise
    (       %     Write the largest integer square root into that position
    tt      %     Duplicate twice
    5M      %     Push again the matrix which is true for the position of maximum
    1Y6     %     Push matrix [0 1 0; 1 0 1; 0 1 0] (von Neumann neighbourhood)
    Z+      %     2D convolution, keeping size. Gives a matrix which is 1 for the
            %     neighbours of the value that was replaced by its square root
    *       %     Multiply. This replaces the value 1 by the actual values of
            %     the neighbours
    t       %     Duplicate
    XzX<    %     Minimum of non-zero entries
    =       %     Equals, element-wise. This gives a matrix which is true at the
            %     position of the maximum neighbour, and zero otherwise
    *       %     Multiply, element-wise. This gives a matrix which contains the
            %     maximum neighbour, and has all other entries equal to zero
    J       %     Push the maximum integer root, which was previously stored
    q       %     Subtract 1
    *       %     Multiply element-wise. This gives a matrix which contains the
            %     maximum neighbour times (maximum integer root minus 1)
    +       %     Add. This replaces the maximum neighbour by the desired value,
            %     that is, the previously found maximum integer square root
            %     times the neighbour value
    w       %     Swap
  }         %   Else. This means there was no integer square root, so no more
            %   iterations are neeeded
  **        %   Multiply element-wise twice. Right before this the top of the
            %   stack contains a zero. Below there are the latest matrix with
            %   square roots and two copies of the latest matrix of integers,
            %   one of which needs to be displayed as final result. The two
            %   multiplications leave the stack containing a matrix of zeros
            %   and the final result below
            % End (implicit). The top of the stack is consumed. It may be a
            % positive number, which is truthy, or a matrix of zeros, which is
            % falsy. If truthy a new iteration is run. If falsy the loop exits
            % Display (implicit)

1

자바 스크립트 (ES6), 271 259 250 245 바이트

m=>{for(l=m.length;I=J=Q=-1;){for(i=0;i<l;i++)for(j=0;j<l;j++)!((q=m[i][j]**.5)%1)&&q>Q&&(I=i,J=j,Q=q);if(I<0)break;d=[[I-1,J],[I+1,J],[I,J-1],[I,J+1]];D=d.map(([x,y])=>(m[x]||0)[y]||1/0);[x,y]=d[D.indexOf(Math.min(...D))];m[x][y]*=Q;m[I][J]=Q}}

−14 바이트의 Luis felipe De jesus Munoz 에게 감사 합니다!

설명:

m => { // m = input matrix
  // l = side length of square matrix
  // I, J = i, j of largest square in matrix (initialized to -1 every iteration)
  // Q = square root of largest square in matrix
  for (l = m.length; (I = J = Q = -1); ) {
    // for each row,
    for (i = 0; i < l; i++)
      // for each column,
      for (j = 0; j < l; j++)
        // if sqrt of m[i][j] (assigned to q) has no decimal part,
        // (i.e. if m[i][j] is a perfect square and q is its square root,)
        !((q = m[i][j] ** 0.5) % 1) &&
          // and if this q is greater than any previously seen q this iteration,
          q > Q &&
          // assign this element to be the largest square in matrix.
          ((I = i), (J = j), (Q = q));
    // if we did not find a largest square in matrix, break loop.
    if (I < 0) break;
    // d = [i, j] pairs for each neighbor of largest square in matrix
    d = [[I - 1, J], [I + 1, J], [I, J - 1], [I, J + 1]];
    // D = value for each neighbor in d, or Infinity if value does not exist
    D = d.map(([x, y]) => (m[x] || 0)[y] || 1 / 0);
    // x = i, y = j of smallest adjacent neighbor of largest square
    [x, y] = d[D.indexOf(Math.min(...D))];
    // multiply smallest adjacent neighbor by square root of largest square
    m[x][y] *= Q;
    // set largest square to its square root
    m[I][J] = Q;
  } // repeat until no remaining squares in matrix
  // no return necessary; input matrix is modified.
};



1

자바 스크립트 (Node.js) 157 바이트

a=>g=(l,m=n=i=j=0)=>a.map((o,k)=>m>o||o**.5%1||[m=o,i=k])|m&&a.map((o,k)=>n*n<o*n|((i/l|0)-(k/l|0))**2+(i%l-k%l)**2-1||[n=o,j=k])|[a[i]=m**=.5,a[j]=m*n]|g(l)

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

-14 바이트 덕분에 @Arnauld도 감사드립니다. :)

1 차원 배열을 입력으로 사용하고 열 / 행의 경우 숫자를 지정하는 길이 매개 변수를 사용하는 익명 함수.

커리 입력은로 지정됩니다 f(array)(length).

// a: 1-dimensional array of values
// g: recursive function that explodes once per recursive call
// l: number of columns, user specified
// m: max square value
// n: min neighbor
// i: index of max square
// j: index of min neighbor
a=>g=(l,m=n=i=j=0)=>
  // use .map() to iterate and find largest square
  a.map((o,k)=>
    // check size of element
    m>o||
    // check if element is a square
    o**.5%1||
    // new max square found, update local variables
    [m=o,i=k])|
  // after first .map() is complete, continue iff a square is found
  // run .map() again to find smallest neighbor
  m&&a.map((o,k)=>
    // check size of element
    n*n<o*n|
    // check relative position of element
    ((i/l|0)-(k/l|0))**2+(i%l-k%l)**2-1||
    // a new smallest neighbor found, update local variables
    [n=o,j=k])|
  // update matrix in-place, largest square is reduced,
  // smallest neighbor is increased
  [a[i]=m**=.5,a[j]=m*n]|
  // make recursive call to explode again
  g(l)

1

Java 8, 299 297 바이트

m->{for(int l=m.length,i,j,I,J,d,M,t,x,y;;m[x][y]*=d){for(i=l,I=J=d=0;i-->0;)for(j=l;j-->0;d=t>d*d&Math.sqrt(t)%1==0?(int)Math.sqrt(m[I=i][J=j]):d)t=m[i][j];if(d<1)break;for(M=-1>>>1,m[x=I][y=J]=d,t=4;t-->0;)try{M=m[i=t>2?I-1:t>1?I+1:I][j=t<1?J-1:t<2?J+1:J]<M?m[x=i][y=j]:M;}catch(Exception e){}}}

바이트를 절약하기 위해 새로운 것을 반환하는 대신 입력 행렬을 수정합니다.

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

설명:

m->{                          // Method with integer-matrix input and no return-type
  for(int l=m.length,         //  Dimension-length `l` of the matrix
      i,j,I,J,d,M,t,x,y;      //  Temp integers
      ;                       //  Loop indefinitely:
       m[x][y]*=d){           //    After every iteration: multiply `x,y`'s value with `d`
    for(I=J=d=0,              //   (Re)set `I`, `J`, and `d` all to 0
        i=l;i-->0;)           //   Loop `i` in the range (`l`, 0]:
      for(j=l;j-->0;          //    Inner loop `j` in the range (`l`, 0]:
          d=                  //      After every iteration: set `d` to:
            t>d*d             //       If `t` is larger than `d` squared
            &Math.sqrt(t)%1==0?
                              //       And `t` is a perfect square:
             (int)Math.sqrt(m[I=i][J=j])
                              //        Set `I,J` to the current `i,j`
                              //        And `d` to the square-root of `t`
            :d)               //       Else: leave `d` the same
        t=m[i][j];            //     Set `t` to the value of `i,j`
    if(d<1)                   //   If `d` is still 0 after the nested loop
                              //   (which means there are no more square-numbers)
      break;                  //    Stop the infinite loop
    for(M=-1>>>1,             //   (Re)set `M` to Integer.MAX_VALUE
        m[x=I][y=J]=d,        //   Replace the value at `I,J` with `d`
        t=4;t-->0;)           //   Loop `t` in the range (4, 0]:
      try{M=                  //    Set `M` to:
            m[i=t>2?          //     If `t` is 3:
                 I-1          //      Go to the row above
                :t>1?         //     Else-if `t` is 2:
                 I+1          //      Go to the row below
                :             //     Else (`t` is 0 or 1):
                 I]           //      Stay in the current row
                              //     (and save this row in `i`)
             [j=t<1?          //     If `t` is 0:
                 J-1          //      Go to the column left
                :t<2?         //     Else-if `t` is 1:
                 J+1          //      Go to the column right
                :             //     Else (`t` is 2 or 3):
                 J]           //      Stay in the current column
                              //     (and save this column in `j`)
             <M?              //     And if the value in this cell is smaller than `M`:
                m[x=i][y=j]   //      Set `x,y` to `i,j`
                              //      And `M` to the current value in `i,j`
               :M;            //     Else: leave `M` the same
      }catch(Exception e){}}} //    Catch and ignore IndexOutOfBoundsExceptions

1

젤리 , 70 67 바이트

’dL½$}©+Ø.,U$;N$¤%®‘¤<®Ạ$Ƈæ.®‘ịÐṂḢ;ḷ;€ị½¥×÷ƭ⁹Ḣ¤¦Ṫ}¥ƒ
×Ʋ$MḢçɗ⁸Ẹ?ƊÐL

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

나는 이것이 훨씬 더 짧게 이루어질 수 있다고 확신하지만, 처음 나타난 것보다 더 어렵다는 것을 알았다. 골프를 잘하려고하면 따라야 할 설명.

정사각 행렬에 해당하는 정수 목록을 가져 와서 최종 분해 행렬을 나타내는 정수 목록을 반환하는 전체 프로그램입니다.

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