사각형 감지


21

0와 (과) 1의 여러 줄 문자열을 취하는 프로그램이나 함수를 작성하십시오 . 다른 문자가 문자열에있을 것이고, 문자열은 항상 1 × 1로 작게 치수 (모든 라인 문자의 같은 수있을 것이다) 직사각형 수 있지만 그렇지 않으면 0's와 1의 임의 배열 될 수있다.

문자열에 선택적인 후행 줄 바꿈이 있다고 가정 할 수 있으며 원하는 경우 및 대신에 두 개의 고유 한 인쇄 가능한 ASCII 문자를 사용할 수 있습니다 .01

문자열에서 및 의 경로로 연결된 모든 영역 이 단색 사각형 인 경우 정확한 값을 인쇄하거나 반환 합니다 . 그렇지 않으면 잘못된 값 이 출력 됩니다.01

의 경로 연결 영역 은 0해당 지역 의 어느 한 0지역에서 다른 모든 지역 0으로 위, 아래, 왼쪽 및 오른쪽으로 만 이동하여 0(그리고 대각선으로 이동 하지 않고 , 다른 곳으로 이동 하지 않음) 다른 모든 지역에 도달 할 수 있음 을 의미합니다 . 문자열 경계 밖으로 이동 하지 마십시오 ). 경로 연결 영역 에도 동일한 아이디어가 적용됩니다 .11

고체 직사각형 의 0집 수단 직사각형의 전체 영역이 충전되지 0S '더 1집. 동일한 아이디어가 1단색 사각형 에도 적용됩니다 .

바이트 단위의 가장 짧은 코드가 이깁니다. Tiebreaker가 이전 답변입니다.

(문자열은 토 로이드 경계 조건으로 둘러싸이지 않습니다 .)

예

1) 이 입력 문자열에는 3 개의 경로로 연결된 영역이 있습니다 (에 대한 2 0및 1 1). 오른쪽 아래 00영역 만 단색 사각형이므로 출력이 잘못됩니다.

0011
0111
0100

2) 이 입력 문자열에는 4 개의 경로로 연결된 영역이 있습니다 ( 0및 모두 2 1). 그들 모두는 단색 사각형이므로 출력이 진실합니다.

0011
0011
1100

3) 이 입력에는 2 개의 경로로 연결된 영역이 있지만 그 중 하나만 단색 사각형이므로 출력이 잘못됩니다.

00000000
01111110
00000000

4) 이 입력은 하나의 경로로 연결된 영역을 가지고 있으며 사소한 단색 사각형이므로 출력이 정확합니다.

11111111
11111111
11111111

테스트 사례

T단지 입력 문자열 수단 truthy 아래 F수단 falsy.

0
T

1
T

00
T

01
T

10
T

11
T

0000000
T

1111111
T

011100100100101100110100100100101010100011100101
T

00
11
T

01
10
T

01
11
F

00
01
F

11
11
T

110
100
F

111
000
T

111
101
111
F

101
010
101
T

1101
0010
1101
0010
T

1101
0010
1111
0010
F

0011
0111
0100
F

0011
0011
1100
T

00000000
01111110
00000000
F

11111111
11111111
11111111
T

0000001111
0000001111
T

0000001111
0000011111
F

0000001111
1000001111
F

1000001111
1000001111
T

1110100110101010110100010111011101000101111
1010100100101010100100010101010101100101000
1110100110010010110101010111010101010101011
1010100100101010010101010110010101001101001
1010110110101010110111110101011101000101111
F

답변:


5

젤리 , 7 바이트

ṣ⁷µ=ḢZE

이것은 @LevelRiverSt의 Ruby answer 와 동일한 알고리즘을 사용합니다 . 실제 알고리즘은 마지막 4 바이트에 적합합니다. 입력 형식을 구문 분석하려면 처음 3 바이트가 필요합니다.

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

작동 원리

ṣ⁷µ=ḢZE  Main link. Argument: t (string)

ṣ⁷       Split t at linefeeds..
  µ      Begin a new, monadic link. Argument: A (list of strings)
    Ḣ    Pop the first string of A.
   =     Compare all other strings in A with the first.
         = compares characters, so this yields a list of Booleans for each string.
         For a truthy input, all pairs of lines now have been transformed in lists
         of only 1's or only 0's. That means all columns must be equal.
     Z   Zip; transpose rows with columns.
      E  Check if all rows (former columns) are equal to each other.

16

젤리 , 11 10 바이트

ṣ⁷^2\⁺€FS¬

@Dennis가 문서화되지 않은 기능을 통해 원래 크기의 절반으로 줄어든 것에 대해 큰 감사를드립니다.

온라인으로 사용해보십시오 ! 삼중 따옴표는 여러 줄 문자열에 대한 것입니다.

설명

기본 알고리즘은 다음과 같습니다. 매 2x2 서브 그리드가 짝수의 1 (또는 동등하게 0)을 갖는 경우 true를 리턴합니다.

다음 중 하나를 가지기 때문에 홀수의 1이 작동하지 않는 이유는 분명합니다.

10  01  00  00  01  10  11  11
00  00  01  10  11  11  10  01

처음 4 개는 같은 것의 회전이며 마지막 4 개에 대해 좌우됩니다. 반사 각도는 사각형의 일부가 될 수 없으므로 왜 유효하지 않습니까?

즉, 모든 2x2 하위 그리드는 다음 중 하나 여야합니다.

00  00  11  01  10  01  10  11
00  11  00  01  10  10  01  11

경계를 보면 다음 "퍼즐 조각"으로 상상할 수 있습니다.

 ___    ___    ___    ___
|   |  | | |  |   |  | | |
|   |  | | |  |---|  |-|-|
|___|  |_|_|  |___|  |_|_|

그리고 퍼즐 조각으로 직사각형이 아닌 사각형을 만들어보십시오 :) (끝이 일치하는 동안)

실제 구현은 다음과 같습니다.

ṣ⁷               Split input by newlines to give rows
  ^2\            Taking overlapping sets of 2 rows at a time: accumulate rows by XOR
                 Note that strings cast to integers automatically for bitwise operators
     ⁺€          Repeat the previous link (⁺), on each (€) element in the resulting array
       F         Flatten the array
        S        Sum (effectively reducing by OR)
         ¬       Logical negation of the result

예를 들어, 입력의 경우

100
010
000
101

우리는 :

  ṣ⁷: ["100", "010", "000", "101"]
 ^2\: [[1, 1, 0], [0, 1, 0], [1, 0, 1]]    (e.g. first entry is "100" ^ "010")
^2\€: [[0, 1], [1, 1], [1, 1]]             (e.g. the first entry is [1^1, 1^0] - this
                                            gives the counts of 1s in each subgrid, mod 2)
   F: [0, 1, 1, 1, 1, 1]
   S: 5                                    (this gives the number of invalid 2x2 subgrids,
                                            which is indeed all but the top left)
   ¬: 0

1
사용한 기능을 문서화 할 수 있습니까? 사람들이 그렇게하면 문서화가 일어날 것입니다!
— CalculatorFeline

납작하게해야합니까?
— CalculatorFeline

@CatsAreFluffy 평평하지 않으면 Jelly가 벡터 목록을 합치려고 시도하고 결과적으로 벡터를 얻습니다
— Sp3000

합계와 합계가 더 좋습니다!
— CalculatorFeline

4
"언급되지 않은 기능"-아하! 그래서 그의 방법 데니스 outgolfs 여러분! : D
— AdmBorkBork

12

루비, 76

->s{j=!r=1
s.lines{|t|i=t.to_i(2)
j&&r&&=(j^i)%t.tr(?0,?1).to_i(2)<1
j=i}
r}

완전히 직사각형으로 구성된 그리드에서 각 라인은 이전 라인과 동일해야하거나 모든 비트가 0에서 1로 반전되고 그 반대도 마찬가지입니다.

이것은 증명하기 쉽다. 한 장의 종이를 잡고 가로와 세로 방향으로 임의의 세로선과 가로선을 그립니다. 이제 두 가지 색상 만 사용하여 사각형의 색상을 지정하십시오. 모든 색상이 각 줄에서 뒤집히는 왜곡 된 바둑판이 생깁니다.

선이 부분적으로 가로 질러 사각형을 그리시겠습니까? 라인의 일부를 삭제하십시오. 3 개의 사각형이 만나는 지점 (2 개의 모서리와 가장자리)이 있으므로 디자인에 색상을 지정하려면 2 가지 이상의 색상이 필요합니다. 따라서 이러한 디자인은이 질문과 관련이 없습니다.

나는 지금까지 대답이 이것을 알아 채지 못한 것에 놀랐습니다.

이 알고리즘은 다른 언어에서는 훨씬 짧아야한다고 생각합니다.

테스트 프로그램에서 언 골프

f=->s{
  j=!r=1                              #r = truthy, j=falsy
  s.lines{|t|                         #for each line
    i=t.to_i(2)                       #i = value of current line, converted to a number in base 2 (binary)
    j&&                               #if j is truthy (i.e this is not the first line)
      r&&=(j^i)%t.tr(?0,?1).to_i(2)<1 #XOR i with the previous line. Take the result modulo (current line with all 0 replaced by 1)
                                      #if the result of the XOR was all 0 or all 1, the modulo == zero (<1). Otherwise, it will be a positive number.   
j=i}                                  #j = value of current line (always truthy in ruby, even if zero)
r}                                    #return 1 or true if all the modulo calculations were zero, else false.



#text to print after test case to check answer is as desired
T='T

'
F='F

'

#test cases
puts f['0'],T

puts f['1'],T

puts f['00
'],T

puts f['01'],T

puts f['10'],T

puts f['11
'],T

puts f['0000000'],T

puts f['1111111'],T

puts f['011100100100101100110100100100101010100011100101'],T

puts f['00
11'],T

puts f['01
10'],T


puts f['01
11'],F

puts f['00
01'],F

puts f['11
11
'],T

puts f['110
100'],F

puts f['111
000'],T

puts f['111
101
111'],F

puts f['101
010
101
'],T

puts f['1101
0010
1101
0010'],T

puts f['1101
0010
1111
0010'],F

puts f['0011
0111
0100
'],F

puts f['0011
0011
1100'],T

puts f['00000000
01111110
00000000'],F

puts f['11111111
11111111
11111111'],T

puts f['0000001111
0000001111'],T

puts f['0000001111
0000011111'],F

puts f['0000001111
1000001111'],F

puts f['1000001111
1000001111'],T

puts f['1110100110101010110100010111011101000101111
1010100100101010100100010101010101100101000
1110100110010010110101010111010101010101011
1010100100101010010101010110010101001101001
1010110110101010110111110101011101000101111'],F

내가 사용 내기 s.scan(/^?.*\n/)바이트 저장 도움이 될 것이다.
— 아니 찰스

3

달팽이 , 20 바이트

!{to{\0w`3\1|\1w`3\0

3 개의 0과 1 또는 3과 1과 0을 0가진 2x2 정사각형이 없거나 그러한 2x2 정사각형이있는 경우 격자 영역을 인쇄 합니다.


3

MATL , 12 바이트

Ybc2thYCs2\~

@ sp3000의 위대한 답변 과 동일한 알고리즘 입니다.

여러 줄 입력을 허용하기 위해 MATL 10은 개행 문자 를 사용하여 명시 적으로 행 문자 배열 (문자열)을 작성해야합니다 . 따라서 네 가지 예의 입력은 다음과 같습니다 ( []연결됨에 따라 각각은 문자의 행 배열입니다).

['0011' 10 '0111' 10 '0100']
['0011' 10 '0011' 10 '1100']
['00000000' 10 '01111110' 10 '00000000']
['11111111' 10 '11111111' 10 '11111111']

마지막 세 가지 테스트 사례는

['0000001111' 10 '1000001111']
['1000001111' 10 '1000001111']
['1110100110101010110100010111011101000101111' 10 '1010100100101010100100010101010101100101000' 10 '1110100110010010110101010111010101010101011' 10 '1010100100101010010101010110010101001101001' 10 '1010110110101010110111110101011101000101111']

Truthy 출력은 하나만 포함 된 배열입니다.

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

설명

이 문자의 패리티는 사실 사용 '0'및 '1'숫자의 것과 동일 0하고 1, 그래서 나타내는 숫자를 문자로 변환하는이 필요 아니에요을,

Yb     % split implicit input by whitespace. Gives a cell array
c      % concatenate cell contents into 2D char array
2th    % push array [2 2]
YC     % get 2×2 sliding blocks and arrange as columns
s      % sum of each column
2\     % modulo 2 of each sum
~      % negate. Implicit display

입력은 문자열이어야합니다
— Calvin 's Hobbies

@HelkaHomba MATL은 여러 줄 문자열 입력을 허용하지 않습니다 ... 입력은 형식의 행 배열이어야합니다 . ['first line' 10 'second llne']여기서 10줄 바꿈의 ASCII입니다. 괜찮습니까?
— Luis Mendo

@ HelkaHomba 나는 업데이트 된 답변에서 그것을 사용했습니다. 또는 줄 바꿈 대신 공백을 사용할 수 있습니까? 첫 번째 예는 문자열입니다.'0011 0111 0100'
— Luis Mendo

@LuisMendo 생각은 고맙지 만, 루비의 대답이 실제로 골퍼라고 생각합니다. :)
— Sp3000

@ Sp3000 아, 나는 그것을 보지 못했습니다. 매우 영리합니다
— Luis Mendo

2

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

s=>!s.split`
`.some((t,i,u)=>[...t].some((v,j)=>v^t[0]^u[0][j]^s[0]))

나는 경로 연결 직사각형 기준이 짝수의 1s 가있는 임의의 직사각형의 모서리를 형성하는 4 개의 점이 주어진 것을 요구하는 것과 같다고 생각합니다 . 사각형 (0, b), (x, y)의 패리티는 (0, b), (a, y) ^(a, b), (x, y)와 동일하므로 확인해야합니다. 왼쪽 상단 모서리가 (0, 0) 인 사각형 또한 De Morgan의 법칙에 따르면 몇 바이트를 절약 !.some()하는 것과 같습니다 .every(!).

편집 : 젤리 솔루션은 모든 2 × 2 직사각형의 모서리 패리티를 확인합니다. 이는 동등한 것으로 표시 될 수 있습니다.


거의 7
— 회지

2

자바 스크립트 (ES6), 79

@ Sp3000의 동일한 젤리 알고리즘과 작동하는지 증명할 필요가 없습니다. 그냥 8 배 이상

s=>[...s].every((x,i)=>[++i,i+=s.search`
`,i+1].some(p=>!(x^=p=s[p],p>`
`))|!x) 

덜 골프

s=>[...s].every((x,i)=> // repeat check for every sub square
     [++i,                  // array of position for next char in row
      i+=s.search`\n`, i+1] // and 2 chars at same column in next row
       .some(p=> // for each position 
          !( 
            x^=s[p],  // xor current value with value at position p
            s[p]>`\n` // true if value at position p is valid
           ) // the condition is negated
       ) // if any value scanned is not valid, .some return true
         // else, we must consider the check for current square
       | !x // x can be 0 or 1, to be valid must be 0
   ) 

테스트 스위트

f=s=>[...s].every((x,i)=>[++i,i+=s.search`
`,i+1].some(p=>!(x^=p=s[p],p>`
`))|!x) 

testData=`
0
T

1
T

00
T

01
T

10
T

11
T

0000000
T

1111111
T

011100100100101100110100100100101010100011100101
T

00
11
T

01
10
T

01
11
F

00
01
F

11
11
T

110
100
F

111
000
T

111
101
111
F

101
010
101
T

1101
0010
1101
0010
T

1101
0010
1111
0010
F

0011
0111
0100
F

0011
0011
1100
T

00000000
01111110
00000000
F

11111111
11111111
11111111
T

0000001111
0000001111
T

0000001111
0000011111
F

0000001111
1000001111
F

1000001111
1000001111
T

1110100110101010110100010111011101000101111
1010100100101010100100010101010101100101000
1110100110010010110101010111010101010101011
1010100100101010010101010110010101001101001
1010110110101010110111110101011101000101111
F`

console.log=x=>O.textContent+=x+'\n'

testData.split('\n\n').forEach(t=>{
  var k=t.slice(-1)=='T',
      r=f(t.slice(0,-1))
  console.log(t+' '+r+ (k==r?' OK\n':' KO\n'))
})  
<pre id=O></pre>


1
이제 8 배 더 깁니다!
— Neil

1

Grime v0.1, 31 바이트

E=\0+|\1+
N=.+&E!
e`(E/N|N/E)#!

1일치하고 일치 0하지 않는 인쇄 합니다 . 온라인으로 사용해보십시오!

설명

Grime은 2D 패턴 일치 언어입니다. 나는 오늘 그것을 수정했지만 구문 요소 () `대신 문자 만 변경하기 ,때문에 점수에 영향을 미치지 않습니다.

나는 그와 유사한 방식 사용하고 SP3000을 : 그것은 그 하나의 행을 모두 포함하는 2 × N 사각형이 포함 된 경우 입력은 falsy이다 0과 1, 다른 행은하지 않습니다.

E=             Define a nonterminal E, which matches
  \0+|           a horizontal run of one or more 0s, OR
      \1+        a horizontal run of one or more 1s.
N=             Define a nonterminal N, which matches
  .+             a horizontal run of one or more characters,
    &E!          which is NOT matched by E (so contains both 0 and 1).
e`             Match entire input to this pattern:
            !    not
           #     contains
  (E/N|N/E)      E on top of N, or N on top of E

1

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

s=>(a=s.split`
`).every(l=>l==a[0]|l==a[0].replace(/./g,n=>n^1))

@LevelRiverSt의 관찰에 따르면 각 줄은 첫 줄과 같거나 반대 여야합니다.

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