가장 큰 광장


9

이 질문은 그리드의 Biggest Square 와 유사합니다 .

도전

매트릭스 주어 1와 0문자열 형식 "xxxx,xxxxx,xxxx,xx.."또는 배열 형식을 ["xxxx","xxxx","xxxx",...], 당신은 모든 것을 포함하는 가장 큰 정사각형 행렬의 영역을 결정하는 함수를 작성합니다 1.

정사각형 하위 행렬은 너비와 높이가 같으며 함수는을 포함하는 가장 큰 하위 행렬의 영역을 반환해야합니다 1.

예를 들어 :

이라고 가정 "10100,10111,11111,10010"하면 다음 행렬과 같습니다.

1,010

1,011 1

1 1 1 1

1,010

굵은 1글씨가 2x2 크기의 가장 큰 정사각형 하위 행렬을 만드는 것을 볼 수 있으므로 프로그램은 4의 영역을 반환해야합니다.

규칙

  • 하위 행렬은 너비와 높이가 같아야합니다
  • 하위 행렬에는 값만 포함해야합니다 1
  • 함수는 가장 큰 하위 행렬의 영역을 반환해야합니다.
  • 하위 행렬을 찾을 수 없으면 1
  • 당신의 수를 계산하여 행렬의 면적을 계산할 수 있습니다 1서브 매트릭스에

테스트 사례

입력 : "10100,10111,11111,10010" 출력 : 4

입력 : "0111,1111,1111,1111" 출력 : 9

입력 "0111,1101,0111" 출력 : 1


이것은 바이트 단위의 최단 답변이 이깁니다.


3
왜 문자열 형식입니까?
— Stewie Griffin

3
입력을 이진 (숫자) 행렬로 취할 수 있습니까?
— Stewie Griffin

5
[0]이 여전히 1을 출력해야합니까?
— l4m2

6
잠깐, 왜 모든 1 하위 행렬을 찾을 수 없을 때 1을 반환하면 0이 더 의미가 없습니까? (그렇지 않으면 단순히 처리하기위한 특별한 경우입니다)
— Jonathan Allan

2
사양을 변경하면 두 답변자가 마음에 들지 않으며 1을 반환 할 필요가 없으므로 제출이 더 흥미로워지지 않기 때문에 그렇게하는 것이 좋습니다.
— ბიმო

답변:


2

젤리 , 18 바이트

+1 전체 서브리스트 존재 출력을 처리하기위한 +2

ẆZṡ¥"L€$ẎȦÐfL€Ṁ²»1

온라인으로 사용해보십시오! 또는 시험 스위트를 참조하십시오

어떻게?

ẆZṡ¥"L€$ẎȦÐfL€Ṁ²»1 - Link: list of lists of 1s and 0s
Ẇ                  - all slices (lists of "rows") call these S = [s1,s2,...]
       $           - last two links as a monad:
     L€            -   length of each (number of rows in each slice) call these X = [x1, x2, ...]
    "              -   zip with (i.e. [f(s1,x1),f(s2,x2),...]):
   ¥               -     last two links as a dyad:
 Z                 -       transpose (get the columns of the current slice)
  ṡ                -       all slices of length xi (i.e. squares of he slice)
        Ẏ          - tighten (to get a list of the square sub-matrices)
          Ðf       - filter keep if:
         Ȧ         -   any & all (all non-zero when flattened?)
            L€     - length of €ach (the side length)
              Ṁ    - maximum
               ²   - square (the maximal area)
                »1 - maximum of that and 1 (to coerce a 0 found area to 1)

대박. 설명을 추가 할 수 있습니까?
— Luis felipe De jesus Munoz

내가 먼저 짧게 생각하려고합니다 ...
— Jonathan Allan

@ Mr.Xcoder 현재 요구 사항을 처리하도록 업데이트되었습니다
— Jonathan Allan

5

하스켈 , 113 121 118 117 바이트

x!s=[0..length x-s]
t#d=take t.drop d
f x=last$1:[s*s|s<-min(x!0)$x!!0!0,i<-x!!0!s,j<-x!s,all(>'0')$s#i=<<(s#j)x,s>0]

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

Laikoni 덕분에 -3 바이트 !

Lynn 덕분에 -1 바이트 !

모든 1의 하위 행렬이 아닌 경우 1을 반환하는 어리석은 요구 사항에 +8 바이트.

설명 / 비 골프

다음 도우미 함수는 다음을 x통해 오프셋을 줄일 수 있도록 오프셋을 만듭니다 s.

x!s=[0..length x-s]

x#yy목록에서 요소를 삭제 하고 다음을 수행합니다 x.

t#d=take t.drop d

이 함수 f는 하위 행렬에 대해 가능한 모든 크기를 순서대로 반복하고 해당 크기의 각 하위 행렬을 생성하며 '1's 만 포함하는지 테스트 하고 크기를 저장합니다. 따라서 솔루션은 목록의 마지막 항목이됩니다.

--          v prepend a 1 for no all-1s submatrices
f x= last $ 1 : [ s*s
                -- all possible sizes are given by the minimum side-length
                | s <- min(x!0)$x!!0!0
                -- the horizontal offsets are [0..length(x!!0) - s]
                , i <- x!!0!s
                -- the vertical offsets are [0..length x - s]
                , j <- x!s
                -- test whether all are '1's
                , all(>'0') $
                -- from each row: drop first i elements and take s (concatenates them to a single string)
                              s#i =<<
                -- drop the first j rows and take s from the remaining
                                      (s#j) x
                -- exclude size 0...........................................
                , s>0
                ]

4

하스켈 , 99 97 바이트

b s@((_:_):_)=maximum$sum[length s^2|s==('1'<$s<$s)]:map b[init s,tail s,init<$>s,tail<$>s]
b _=1

입력이 s==('1'<$s<$s), 1 인 경우 정답이 length ^ 2, 그렇지 않은 경우 0 의 정사각 행렬인지 확인 합니다. 그런 다음 첫 번째 / 마지막 열 / 행을 재귀 적으로 잘라 내고 어디서나 찾은 최대 값을 취합니다.

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



3

J , 33 27 바이트

FrownyFrog 덕분에 -6 바이트!

[:>./@,,~@#\(#**/)@,;._3"$]

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

설명:

설명에 첫 번째 테스트 사례를 사용하겠습니다.

    ] a =. 3 5$1 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 0 0 1 0
1 0 1 0 0
1 0 1 1 1
1 1 1 1 1

1에서 입력 행 수까지의 크기로 가능한 모든 정사각형 서브 매트릭스를 생성합니다.

,~@#\입력 ,.의 연속 접두사 길이를 스티칭하여 하위 행렬의 크기에 대한 쌍 목록을 작성합니다 #\.

   ,~@#\ a
1 1
2 2
3 3

그런 다음 그것들을 사용 x u ;. _3 y하여 입력을 하위 행렬 로 자릅니다 . 나는 이미 x(크기 목록)을 가지고 있습니다. y올바른 인수입니다 ](입력).

 ((,~@#\)<;._3"$]) a
┌─────┬─────┬─────┬───┬─┐
│1    │0    │1    │0  │0│
│     │     │     │   │ │
│     │     │     │   │ │
├─────┼─────┼─────┼───┼─┤
│1    │0    │1    │1  │1│
│     │     │     │   │ │
├─────┼─────┼─────┼───┼─┤
│1    │1    │1    │1  │1│
└─────┴─────┴─────┴───┴─┘

┌─────┬─────┬─────┬───┬─┐
│1 0  │0 1  │1 0  │0 0│ │
│1 0  │0 1  │1 1  │1 1│ │
│     │     │     │   │ │
├─────┼─────┼─────┼───┼─┤
│1 0  │0 1  │1 1  │1 1│ │
│1 1  │1 1  │1 1  │1 1│ │
├─────┼─────┼─────┼───┼─┤
│     │     │     │   │ │
└─────┴─────┴─────┴───┴─┘

┌─────┬─────┬─────┬───┬─┐
│1 0 1│0 1 0│1 0 0│   │ │
│1 0 1│0 1 1│1 1 1│   │ │
│1 1 1│1 1 1│1 1 1│   │ │
├─────┼─────┼─────┼───┼─┤
│     │     │     │   │ │
│     │     │     │   │ │
├─────┼─────┼─────┼───┼─┤
│     │     │     │   │ │
└─────┴─────┴─────┴───┴─┘

각 하위 행렬에 대해 완전히 1로 구성되어 있는지 확인합니다 (#**/)@,.-행렬을 평탄화하고 제품별로 항목 수를 곱합니다. 모든 항목이 1이면 결과는 합계가되고, 그렇지 않으면-0입니다.

   (#**/)@, 3 3$1 0 0 1 1 1 1 1 1
0
   (#**/)@, 2 2$1 1 1 1
4 

   ((,~@#\)(+/**/)@,;._3"$]) a
1 0 1 0 0
1 0 1 1 1
1 1 1 1 1

0 0 0 0 0
0 0 4 4 0
0 0 0 0 0

0 0 0 0 0
0 0 0 0 0
0 0 0 0 0

마지막으로 각 하위 행렬에 대한 결과 목록을 평면화하고 최대 값을 찾습니다.

>./@,

   ([:>./@,,~@#\(+/**/)@,;._3"$]) a
4

1
,~@#\및 "1 2->"$
— FrownyFrog

@FrownyFrog 감사합니다! 나는 몰랐다"$
— Galen Ivanov

1
#1을 더하는 것보다 짧습니다.
— FrownyFrog

@ FrownyFrog 흠, 정말입니다. 감사합니다!
— Galen Ivanov


2

레티 나 143 바이트

%`$
,;#
+%(`(\d\d.+;#)#*
$1¶$&¶$&#
\G\d(\d+,)|\G((;#+¶|,)\d)\d+
$1$2
)r`((11)|\d\d)(\d*,;?#*)\G
$#2$3
1,
#
Lv$`(#+).*;\1
$.($.1*$1
N`
-1G`
^$
1

온라인으로 사용해보십시오! 링크에는 테스트 사례가 포함됩니다. 쉼표로 구분 된 문자열로 입력을받습니다. 설명:

%`$
,;#

,마지막 문자열을 종료하려면 a 를 추가 ;하고 문자열을 #s 에서 분리하고 #a를 카운터로 추가하십시오.

+%(`
)

더 이상 대체가 발생하지 않을 때까지 블록을 반복하십시오 (각 문자열의 길이가 이제 한 자릿수이므로).

(\d\d.+;#)#*
$1¶$&¶$&#

첫 줄에서 카운터를 1로 설정하고 마지막 줄에서 카운터를 증가시켜 줄을 세 번 반복합니다.

\G\d(\d+,)|\G((;#+¶|,)\d)\d+
$1$2

첫 번째 줄에서 각 문자열의 첫 번째 숫자를 삭제하고 두 번째 줄에서 첫 번째 숫자를 제외한 모든 숫자를 삭제하십시오.

r`((11)|\d\d)(\d*,;?#*)\G
$#2$3

세 번째 줄에는 비트 단위와 처음 두 자리 숫자가 함께 있습니다.

1,
#

이 시점에서 각 줄은 a) 가로 너비 카운터와 b) 비트 단위 및 각 문자열에서 가져온 많은 비트의 두 값으로 구성됩니다. 나머지 1s를 #s로 변환 하여 카운터와 비교할 수 있도록합니다.

Lv$`(#+).*;\1
$.($.1*$1

1원래 입력에서 s의 제곱에 해당하는 카운터 (수평)와 일치하는 비트 수 (수직)를 찾아 길이를 제곱합니다.

N`

숫자로 정렬하십시오.

-1G`

가장 큰 것을 가져 가라.

^$
1

제로 행렬을 특수한 경우.


2

자바 스크립트, 92 바이트

a=>(g=w=>a.match(Array(w).fill(`1{${w}}`).join(`..{${W-w}}`))?w*w:g(w-1))(W=a.indexOf`,`)||1


2

APL (Dyalog Classic) , 21 20 바이트

×⍨{1∊⍵:1+∇2×/2×⌿⍵⋄0}

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


재귀! 좋은!
— Zacharý

@ Zacharý 감사합니다. 실제로 재귀 대신 모나 딕 f의 경우 k의 f \ x와 같은 것을 선호합니다. 수렴 할 때까지 (x; fx; ffx; ...)이지만 APL (아직)에는 해당 사항이 없습니다. ⍣≡를 사용하면 너무 많은 바이트가 필요합니다.
— ngn

2

파이썬 2 , 117109 바이트

추가 바이트 비용이 드는 비 효율성을 지적한 @etene에게 감사드립니다.

lambda s:max(i*i for i in range(len(s))if re.search(("."*(s.find(',')-i+1)).join(["1"*i]*i),s))or 1
import re

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

쉼표로 구분 된 문자열로 입력을받습니다. 이것은 정규식 기반의 접근 방식으로 입력 문자열을 111.....111.....111가능한 모든 크기의 사각형 에 대한 형식의 패턴과 일치시킵니다 .

내 계산에서 익명 람다로 이것을하는 것은 정의 된 함수 또는 전체 프로그램보다 약간 짧습니다. 마지막 or 1부분은 이상한 가장자리를 처리하는 데에만 필요합니다 1. 입력에 아무도 없으면 출력해야합니다 .


2

파이썬 (2) , 116 (115) 117 109 바이트

골프를 더 영리하게 도와주는 영리한 초기 솔루션으로 @Kirill에게 감사의 뜻을 전합니다.

편집 : 람다를 사용하여 1 바이트 골프를 쳤지 만 변수에 할당하는 것이 바이트 수에 포함되지 않았다는 것을 몰랐습니다.

편집 2 : Kirill은 입력에 1s 만 포함 된 경우 내 솔루션이 작동하지 않는다고 지적 했으며이를 수정하고 두 개의 소중한 바이트를 잃어 버렸습니다 ...

편집 3 : Kirill 덕분에 더 많은 골프

쉼표로 구분 된 문자열을 가져와 정수를 반환합니다.

lambda g:max(i*i for i in range(len(g))if re.search(("."*(g.find(",")+1-i)).join(["1"*i]*i),g))or 1
import re

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

Kiril의 답변과 가까운 답을 찾았습니다. 즉, 정규 표현식을 사용 re.search 합니다def .

각 루프 중에 생성 된 정규 표현식을 사용하여 점차적으로 큰 사각형을 일치시키고 가장 큰 사각형 또는 1을 반환합니다.


1
멋지게, 나는 어쨌든 자동으로 if접근 방식을 "너무 오랫동안 너무 오래" 버렸다 . 불행히도, 당신의 솔루션은 한 가지 점을 그리워합니다-당신은 그저 가질 수 없습니다 range(l)-전혀 0이없는 경우를 놓칠 것입니다. 예를 들어, 두 번째 테스트 케이스를 가져 와서 모두 1로 만듭니다. 9가 아니라 16이되어야합니다.
— Kirill L.

젠장, 나는 모든 0으로 테스트하는 것이 아니라 모든 0으로 테스트하는 것에 대해 생각했습니다 (도전에서는 언급하지 않았습니다 ...). 나는 무언가를 만들려고 노력할 것이다.
— etene

@KirillL. 그건 그렇고, 당신은 빠릅니다! 나는 당신이 당신의 것을 올렸을 때 여전히 내 대답에 노력하고 있었고 우리의 접근 방식이 비슷하다는 것을 알았을 때 약간 화려했습니다 (그리고 자랑스러워했습니다!).
— etene

1
중복을 제거하여 몇 바이트 더 골프를 쳤다 find. 이제 코드가 더 이상 동일하지 않으므로 적어도 분명한 실수를 수정하는 것이 좋습니다. 여러분의 경우 여분의 바이트가 ("1"*i,)list 대신 tuple을 사용하여 발생 합니다.
— Kirill L.

고마워요, 예, 쓸모없는 튜플은 꽤 바보입니다. 그리고 엑스트라 find도, 그것은 당신의 영리했습니다.
— etene




1

클로저, 193 바이트

#(apply max(for [f[(fn[a b](take-while seq(iterate a b)))]R(f next %)R(f butlast R)n[(count R)]c(for[i(range(-(count(first R))n -1)):when(apply = 1(for[r R c(subvec r i(+ i n))]c))](* n n))]c))

와, 상황이 확대되었습니다 : o

덜 골프 :

(def f #(for [rows (->> %    (iterate next)    (take-while seq)) ; row-postfixes
              rows (->> rows (iterate butlast) (take-while seq)) ; row-suffixes
              n    [(count rows)]
              c    (for[i(range(-(count(first rows))n -1)):when(every? pos?(for [row rows col(subvec row i(+ i n))]col))](* n n))] ; rectangular subsections
          c))
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.