사각형 감지


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이다 01, 다른 행은하지 않습니다.

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.