가장 큰 광장


9

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

도전

매트릭스 주어 10문자열 형식 "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.