長方形の検出


21

0および1の複数行の文字列を取り込むプログラムまたは関数を作成します。文字列には他の文字は含まれず、文字列は常に長方形(すべての行に同じ数の文字が含まれます)で、寸法は1×1ですが、それ以外の場合は0'と1'は任意に配置できます。

あなたは、文字列は、オプションの末尾の改行を持っていると仮定して、必要に応じて、あなたは、任意の2つの異なる使用することができ、印刷可能なASCII文字の代わりに文字を0して1

印刷または戻りtruthy値を場合、すべてパスが接続されているの領域を両方0のと1のある文字列内の固体の長方形、他の出力falsy値

パス接続領域0「いずれかからのS手段0領域内の、すべての他0のだけ上方に移動することによって到達することができるが、上下、左右他方へ0の(としない、斜めに移動しない任意に移動し1、そして文字列の境界の外側に移動しない)。同じ考え方が1パス接続されたリージョンにも適用されます。

実線の長方形0、長方形の領域全体がで塗りつぶされてい0ないことを意味します1。同じ考えが塗りつぶされた1長方形にも当てはまります。

バイト単位の最短コードが優先されます。Tiebreakerは以前の回答です。

(ストリングはトロイダル境界条件でラップアラウンドしないことに注意してください。)

1)この入力文字列には、3つのパス接続領域があります(2に対して01、1に対して1 1)。00ただし、右下の領域のみが塗りつぶされた長方形であるため、出力は偽になります。

0011
0111
0100

2)この入力文字列には、4つのパス接続領域があります(両方0とに2つ1)。それらはすべて実線の長方形であるため、出力は真実です。

0011
0011
1100

3)この入力には2つのパス接続領域がありますが、そのうちの1つだけが塗りつぶされた長方形であるため、出力は偽になります。

00000000
01111110
00000000

4)この入力には1つのパス接続領域のみがあり、単純な長方形であるため、出力は真実です。

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
使用した機能を文書化してください。人々がそうすれば、文書化が行われます!
電卓

平らにする必要がありますか?
電卓

@CatsAreFluffy平坦化しない場合、Jellyはベクトルのリストを合計しようとし、結果としてベクトルを取得します
Sp3000

合計と合計が良いです!
CalculatorFeline

4
「文書化されていない機能」-ああ!それデニスが誰よりもゴルフを上回っている方法です!: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に、またはその逆に反転している必要があります。

これは簡単に証明できます。一枚の紙を取り、それを横切って任意の垂直線と水平線を描きます。ここで、2色のみを使用して長方形に色を付けます。最終的に、すべての色が各行で反転する、歪んだチェッカーボードになります。

途中までしか線のない長方形を描きたいですか?いずれかの行のセグメントを削除してみてください。3つの長方形が交わるポイント(2つのコーナーと1つのエッジ)があるため、デザインに色を付けるには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つのゼロと1つまたは3つの1とゼロを持つ2x2の正方形がない場合、または0そのような2x2の正方形が存在する場合、グリッドの領域を印刷します。


3

MATL、12バイト

Ybc2thYCs2\~

@ sp3000の素晴らしい答えと同じアルゴリズム。

複数行の入力を許可するには、MATLで行の文字配列(文字列)を10改行文字を使用して明示的に構築する必要があります。したがって、4つの例の入力は次のとおりです([]連結であるため、これらはそれぞれ文字の行配列です)。

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

最後の3つのテストケースは

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

真の出力は、1つのみを含む配列です。

オンラインでお試しください!

説明

これは、chars '0'およびのパリティが'1'number 0およびのパリティと同じであるという事実を使用している1ため、charからそれが表す数字に変換する必要はありません。

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

入力は文字列である必要があります
カルビンの趣味

@HelkaHomba MATLは、複数行の文字列の入力を許可しない...入力フォームの行配列でなければならない['first line' 10 'second llne']10改行のASCIIです。それは受け入れられますか?
ルイスメンドー

@HelkaHomba更新された回答でそれを使用しました。あるいは、改行の代わりにスペースを使用できますか?最初の例は文字列です'0011 0111 0100'
ルイスメンドー

@LuisMendo私はその考えに感謝していますが、Rubyの答えは実際にはここで一般的にゴルファーかもしれないと思います:)
Sp3000

@ Sp3000ああ、私はそれを見なかった。非常に賢い
ルイスメンドー

2

JavaScript(ES6)、69バイト

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

パスの連結性の四角形の基準は、任意の四角形の角を形成する4つのポイントが与えられ、偶数の1s があることを要求することと同等であると考えています。長方形(0、b)、(x、y)のパリティは(0、b)、(a、y)(a、b)、(x、y)と同じな^ので、チェックするだけです左上隅が(0、0)にある長方形。また、De Morganの法則による!.some()と、.every(!)数バイトの節約になります。

編集:Jellyソリューションは、すべての2×2の長方形の角のパリティをチェックします。これは同等であることが示されています。


ほぼ7回ですが、+ 1
edc65

2

JavaScript(ES6)、79

@ Sp3000からのJellyの答えと同じアルゴリズム(そして、それが機能することを証明する必要がないのは嬉しいことです)。わずか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倍になりました!
ニール

1

グライム v0.1、31バイト

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

1一致する場合と一致0しない場合に印刷します。オンラインでお試しください!

説明

グライムは私の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

JavaScript(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.