2D 배열에서 가장 큰 사각형


26

입력

게시판 : 2D 컨테이너 (매트릭스, 목록 목록 등)는 다음과 같습니다.

  ["B", "C", "C", "C", "C", "B", "B", "C", "A", "A"],
  ["B", "A", "C", "B", "B", "A", "B", "B", "A", "A"],
  ["B", "C", "B", "C", "A", "A", "A", "B", "C", "B"],
  ["B", "B", "B", "A", "C", "B", "A", "C", "B", "A"],
  ["A", "A", "A", "C", "A", "C", "C", "B", "A", "C"],
  ["A", "B", "B", "A", "A", "C", "B", "C", "C", "C"],
  ["C", "B", "A", "A", "C", "B", "B", "C", "A", "A"]

리스트리스트를 선택하면 모든 서브리스트의 길이가 같다고 가정 할 수 있습니다.

규칙

  • 유효한 사각형을 만들려면 동일한 '문자'를 가진 모든 사각형 모서리가 필요합니다.
  • 예를 들어, X 벨로우가 있는 샘플 보드를 보십시오 . (1,0), (4,0), (1,3) 및 (4,3)에서 'X'를 볼 수 있습니다. 그러면 [1,0,4,3]은 (1,0) ~ (4,3) :

X가있는 샘플 보드 :

  ["B", "X", "C", "C", "X", "B", "B", "C", "A", "A"],
  ["B", "A", "C", "B", "B", "A", "B", "B", "A", "A"],
  ["B", "C", "B", "C", "A", "A", "A", "B", "C", "B"],
  ["B", "X", "B", "A", "X", "B", "A", "C", "B", "A"],
  ["A", "A", "A", "C", "A", "C", "C", "B", "A", "C"],
  ["A", "B", "B", "A", "A", "C", "B", "C", "C", "C"],
  ["C", "B", "A", "A", "C", "B", "B", "C", "A", "A"]
  • 목표는 (오른쪽 + 왼쪽 + 1) * (하단 + 1)에 의해 계산 된 사각형 또는 가장 큰 영역을 가진 사각형 중 하나를 찾는 것입니다
  • 최대 면적이 동일한 직사각형이 여러 개인 경우 하나를 출력하십시오. 선택적으로 (상위 좌표, 왼쪽 좌표, 오른쪽 좌표, 아래쪽 좌표) 사 전형적으로 가장 작은 것.
  • 사각형의 가장자리는 보드의 가장자리와 평행해야합니다.
  • 각 문자는 A에서 Z까지 인쇄 가능한 ASCII 문자입니다 (둘 다 포함).

산출

출력은 가장 큰 영역 사각형 모서리의 왼쪽 및 오른쪽 위치 여야합니다. 첫 번째 샘플 "보드"의 경우 큰 사각형은 노란색입니다.

여기에 이미지 설명을 입력하십시오

대답은 다음과 같아야합니다.

[1, 1, 8, 4]

두 번째 예제 테스트 사례

다음의 입력 :

["C", "D", "D", "D", "A", "A"],
["B", "D", "C", "D", "A", "A"],
["B", "D", "D", "C", "A", "C"],
["B", "D", "B", "C", "A", "C"]

6 개의 사각형 영역을 식별하는 다음 세 좌표 목록 중 하나를 생성해야합니다.

[1, 0, 2, 2]
[1, 0, 3, 1]
[3, 2, 5, 3]

이 질문은 제목과 함께 스택 오버플로에 게시 됩니다. 네 개의 동일한 모서리로 구성된 2D 배열에서 가장 큰 사각형을 찾는 방법은 무엇입니까? 그리고이 무례한 JS 솔루션으로 (내 코드이기 때문에 "무례"라고 말할 수 있습니다.) :

좋아, 내 첫 번째 게시물입니다, 나와 관용하십시오. 퀴즈를 개선하기 위해 당신이 말하는 모든 것을 바꿀 것입니다.


7
안녕하세요, PPCG에 오신 것을 환영합니다! 이것은 좋은 도전으로 보이지만 승리 기준이 부족한 것 같습니다. 일반적으로 여기의 게시물에는 [code-golf]로 태그가 지정되어 가장 짧은 코드 (바이트)가 이깁니다.
— 코너 오브라이언

1
질문을 주 사이트에 게시하기 전에 질문에 대한 피드백을받는 데 사용할 수 있는 샌드 박스가 있음을 알려드립니다 . 샌드 박스는 여기에있는 거의 모든 사람에게, 특히 우리가 가진 모든 규칙과 기대치를 알지 못하는 초보자에게 유용합니다.
— 밀 마법사

2
일부 답변은 예에서 볼 수 있듯이 (왼쪽, 위쪽, 오른쪽, 아래쪽) 대신 "첫 번째"사각형 (즉, 위쪽, 왼쪽, 아래쪽, 오른쪽)에 대한 정렬 순서로 좌표를 출력합니다. 이거 괜찮아?
— nimi

2
덜 엄격한 출력 형식은 일반적으로 더 많은 답변을 장려하므로 이와 비슷한 것도 ((left,top),(right,bottom))좋습니다. 질문이 완전히 수정되면 답변을 삭제하고 다시 답변합니다.
— 앙

1
물론, 당신이 대답을 받아들이려고한다면 전체적으로 가장 짧아야합니다. 이것이 대부분의 사람들이 사이트에서하는 일을 좋아하는 방식입니다. 그러나 그렇게하지 않으면 아무런 결과가 없습니다. 답변을 받아들이는 것이 사이트에 해롭다는 의견 도 커지고 있습니다. 나는 그런 견해를 가지고 있으므로 도전에 대한 답변을 결코 받아들이지 않습니다. 당신이하는 일은 당신에게 달려 있습니다.
— 위트 마법사

답변:


6

파이썬 2 , 148130 바이트

lambda x,e=enumerate:min(((a-c)*(d-b),b,a,d,c)for a,y in e(x)for c,k in e(x)for b,g in e(y)for d,h in e(y)if g==h==k[b]==k[d])[1:]

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


안녕하세요 @ovs, Angs가 제안한대로 (x2-x1 + 1) × (y2-y1 + 1)로 영역을 계산하도록 규칙을 변경하면 불편하고 불편합니까?
— danihp

더 많은 답변을 장려하기 위해 몇 가지 규칙을 완화하고 싶습니다. 할 수 있습니까?
— danihp

@danihp 계속하십시오. 이것은 내 대답을 무효화하지 않습니다.
— ovs

응, 네 대답이 맞아! 좋은.
— danihp

5

망막 , 163 162 바이트

Lw$`(?<=(.*\n)*((.)*))(?=(.))((.)*(?<=(.*))\4)((.*\n)*((?>(?<-3>.)*)(?=\4)(?>(?<-6>.)*))\4)?
$.7,$#1,$.2,-$.($5$#9*$5),$.2,$#1,$.7,$.($#1*_$#9*
4{N`
)m`^.*?,

0G`

온라인으로 사용해보십시오! 편집 : )일치하는 후행 $.(이 암시 적이므로 1 바이트를 저장했습니다 . 설명:

Lw$`(?<=(.*\n)*((.)*))(?=(.))((.)*(?<=(.*))\4)((.*\n)*((?>(?<-3>.)*)(?=\4)(?>(?<-6>.)*))\4)?

이 정규식은 사각형과 일치합니다. 그룹은 다음과 같습니다. 1) 맨 위 행 (캡처 카운트) 2) 왼쪽 열 (길이) 3) 왼쪽 모서리 정렬을위한 균형 조정 4) 모서리 문자 5) 너비 + 1 (길이) 6) 균형 조정 오른쪽 모서리가 정렬되도록 7) 오른쪽 열 (길이) 8) 사용하지 않음 9) 높이 (캡처 카운트). 이 w옵션을 사용하면 가능한 모든 직사각형 너비가 주어진 각 왼쪽 상단 모서리와 일치합니다. $옵션리스트 다음과 같은 대체 패턴을 사용하여 결과.

$.7,$#1,$.2,-$.($5$#9*$5),$.2,$#1,$.7,$.($#1*_$#9*

대체는 다음과 같습니다. 오른쪽 열, 맨 위 행, 왼쪽 열, 사각형 영역의 부정 (문자열을 여러 번 반복하여 높이를 여러 번 반복 한 길이로 계산), 왼쪽 열 , 맨 위 행, 오른쪽 열, 맨 아래 행으로 평가되는 표현식이 뒤 따릅니다 (캡처 비용은 12 바이트이며 한 자리 변수가 부족합니다). 처음 4 개의 캡처는 우선 순위에 따라 정렬 순서를 나타냅니다. Retina가 안정적으로 정렬됨에 따라 각 정렬 열을 순서대로 정렬하여 다중 열 정렬을 설정할 수 있습니다. 이 영역은 내림차순으로 정렬해야하므로 단일 문자열 정렬을 사용할 수 없습니다.

4{N`

그런 다음 네 가지 숫자 정렬이 수행됩니다.

)m`^.*?,

그런 다음 각 정렬 후에 정렬 열이 삭제됩니다.

0G`

따라서 첫 번째 항목은 이제 원하는 결과입니다.

참고 : 주어진 영역의 사각형 선택에 대한 제한이 완화되었으며 다음 144143 바이트 버전은 더 큰 사각형보다 넓은 것을 선호합니다.

Lw$`(?<=(.*\n)*((.)*))(?=(.))((.)*(?<=(.*))\4)((.*\n)*((?>(?<-3>.)*)(?=\4)(?>(?<-6>.)*))\4)?
-$.($5$#9*$5);$.2,$#1,$.7,$.($#1*_$#9*
N`
0G`
.*;

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


사전 최소 요구 사항을 충족하지 못합니다 (예를 들어 OP에 추가 한 테스트 사례를 시도하십시오) (출력이 잘못된 순서 일 수도 있습니다 ??). TIO
— Jonathan Allan

(... 예, 출력에서 ​​처음 두 값은 잘못된 생각입니다.)
— Jonathan Allan

방금 몇 가지 제한 사항을 완화했습니다 (사전 최소 요구 사항). 나는 당신에게 문제가되지 않기를 바랍니다.
— danihp

... 이제 선과 점이 일치해야합니다.
— Jonathan Allan

사전 순서가 20 바이트 인 고정 비용 :-( 그리고 나는 면적 계산이 바뀌고 또 다른 2 바이트가 필요하다는 것을 알았지 만 @JonathanAllan이 포인트에 대해 무엇을 의미하는지 모르겠다.
— Neil

4

젤리 , (27?)  29  28 바이트

1 기반 색인 작성이 허용되는 경우 27-후행 제거 ’

Fṙ1s2;Uœị³EaZI‘P
ZLpLŒċÇÞṪF’

전체 프로그램.

온라인으로 사용해보십시오! (또는 다른 테스트 사례 참조)

방법?

Fṙ1s2;Uœị³EaZI‘P - Link 1, areaOrZero: list of pairs [[b,l],[t,r]]
F                - flatten the input                 [b,l,t,r]
 ṙ1              - rotate left one                   [l,t,r,b]
   s2            - split into twos                   [[l,t],[r,b]]
      U          - upend the input                   [[l,b],[r,t]]
     ;           - concatenate                       [[l,t],[r,b],[l,b],[r,t]]
         ³       - program's input
       œị        - multidimensional index into
          E      - all equal?                       X
            Z    - transpose the input              [[b,t],[l,r]]
           a     - logical AND (vectorises)         (if not X we now have [[0,0],[0,0]]
             I   - incremental differences          [t-b,r-l] (or [0,0] if not X)
              ‘  - increment (vectorises)           [t-b+1,r-l+1] (or [1,1] if not X)
               P - product                          area (or 1 if not X)

ZLpLŒċÇÞṪF’ - Main link: list of lists
Z           - transpose the input
 L          - length
   L        - length of the input
  p         - Cartesian product
    Œċ      - pairs with replacement
       Þ    - (stable) sort by:
      Ç     -   last link (1) as a monad
        Ṫ   - tail (note that the rightmost pre-sort represents the bottom-right 1x1
            -       so cannot be superseded by a non-matching rectangle)
         F  - flatten
          ’ - decrement (vectorises) (to get to 0-based indexing)

4

펄 6 , 83 73 바이트

{([X] (^$^a[0]X ^$a)xx 2).max:{[eq] $a[.[*;1];.[*;0]]and[*] 1 X-[Z-] $_}}

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

리스트의리스트를 돌려줍니다 ((x0 y0) (x1 y1)).

설명

{
  ([X]                   # Cross product of corner pairs.
    (^$^a[0]             # Range of x coords.
     X                   # Cross product of coords.
     ^$a                 # Range of y coords.
    )xx 2                # Duplicate list.
  ).max:                 # Find maximum of all ((x0 y0) (x1 y1)) lists
  {                      # using the following filter.
    [eq]                 # All letters equal?
      $a[.[*;1];.[*;0]]  # Multidimensional subscript with y and x coord pairs.
    and                  # Stop if false.
    [*]                  # Multiply
      1 X-[Z-] $_        # for each axis 1 - (c0 - c1) == c1 - c0 + 1.
  }
}

3

하스켈 , 144 바이트

import Data.Array
o=assocs
f r=snd$maximum[((c-a+1)*(d-b+1),[a,b,c,d])|((a,b),x)<-o r,((c,d),y)<-o r,x==y,r!(a,d)==r!(c,b),x==r!(a,d),a<=c,b<=d]

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


b<=d보관하는 한 제거 할 수 있습니다 a<=c.
— 밀 마법사

@ovs는 실제로 작동하지 않습니다 ( TIO를 추가 한 예 참조 )
— Jonathan Allan

@ nimi : 나는 그것이 입력을 바꾸는 것의 문제라고 주장 할 수 있습니다.
— 앙

나는 괜찮아. 입력을 바꿉니다.
— danihp


3

자바 스크립트 (ES6), 121 바이트

@ l4m2 덕분에
-1 바이트 새로운 사각형 점수 규칙을 준수하기 위해 @tsh +2 바이트 덕분에 -1 바이트

입력을 문자열 매트릭스로 취합니다. 0으로 색인 된 좌표를 반환합니다 : [x0, y0, x1, y1] .

a=>a.map(b=(r,y)=>r.map((v,x)=>a.map((R,Y)=>R.map((V,X)=>V+R[x]+r[X]!=v+v+v|(A=(x+~X)*(y+~Y))<b||(o=[x,y,X,Y],b=A)))))&&o

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


a=>a.map(b=(r,y)=>r.map((v,x)=>a.map((R,Y)=>R.map((V,X)=>V+R[x]+r[X]!=v+v+v|(A=(X-x)*(Y-y))<=b||(o=[x,y,X,Y],b=A)))))&&o
— l4m2

최대 면적이 동일한 직사각형이 여러 개인 경우 하나를 출력하십시오 . 아마도 (A=...)<=b-> (A=...)<b?
— tsh

@tsh 이제 안전합니다. 감사!
— Arnauld


1

자바 8, 208205 바이트

m->{int r=0,R[]={},i=m.length,j,y,z,u,t,T;for(;i-->0;)for(j=m[i].length;j-->0;)for(y=i*j;y-->0;)if((T=m[i][j])==m[u=y/j][z=y%j]&T==m[i][z]&T==m[u][j]&r<(t=(i-u)*(j-z))){r=t;R=new int[]{z,u,j,i};}return R;}

확실히 골프를 칠 수 있습니다. 이제는 가장 확실한 방법을 사용합니다. 네 개의 네 개의 중첩 for 루프를 합니다.

덕분에 -3 바이트 행과 열의 내부 루프를 단일 루프로 결합하는 @ceilingcat .

설명:

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

m->{                         // Method with char-matrix parameter and int-array return-type
  int r=0,                   //  Largest area found, starting at 0
      R[]={},                //  Result coordinates, starting empty
      i=m.length,j,          //  x,y indices of the first corner
      y,z,                   //  x,y indices of the second corner
      u,t,T;                 //  Temp integers to reduce bytes
  for(;i-->0;)               //  Loop `i` over the rows
    for(j=m[i].length;j-->0;)//   Inner loop `j` over the columns
      for(y=i*j;y-->0;)      //    Inner loop over the rows and columns
        if((T=m[i][j])==m[u=y/j][z=y%j]
                             //      If the values at coordinates [i,j] and [y,z] are equal
           &T==m[i][z]       //      as well as the values at [i,j] and [i,z]
           &T==m[u][j]       //      as well as the values at [i,j] and [y,j]
           &r<(t=(i-u)*(j-z))){
                             //      And the current area is larger than the largest
          r=t;               //       Set `r` to this new largest area
          R=new int[]{z,u,j,i};}
                             //       And save the coordinates in `R`
  return R;}                 //  Return the largest rectangle coordinates `R`
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.