Dikdörtgen algılama


21

Bir çok satırlı dize alır bir program veya fonksiyon yazın 0'ler ve 1' s. Dizede başka hiçbir karakter bulunmayacak ve dize her zaman dikdörtgen olacak (tüm satırlar aynı sayıda karaktere sahip olacak), boyutları 1 × 1 kadar küçük olacak, ancak aksi halde 0'ler ve 1' ler isteğe göre düzenlenebilir.

Sen dize isteğe bağlı sondaki yeni satır olduğunu varsayalım olabilir ve istenirse herhangi iki farklı kullanabilir yazdırılabilir ASCII yerine karakterleri 0ve 1.

Baskı veya iade truthy değeri ise bütün bir yolun bağlı bölgelerini hem 0'ler ve 1' ler vardır dizede katı dikdörtgenler , başka çıkışı falsy değer .

Bir yol bağlantılı bölge arasında 0'herhangi birinden elde edilen ler vasıtasıyla 0bölgede, diğer 0' in sadece yukarı hareket ulaşılabilir, aşağı, sol ve sağ diğer 0sitesindeki (ve değil , çapraz hareket olmayan herhangi bir hareket 1, ve dizi sınırları dışına çıkmamak ). Aynı fikir 1yola bağlı bölgeler için de geçerlidir .

Bir katı dikdörtgen bir 0bireyin vasıtasıyla dikdörtgen tüm alanı ile doldurulur 0s 've hiçbir 1Var. Aynı fikir 1sağlam dikdörtgenler için de geçerlidir .

Bayt cinsinden en kısa kod kazanır. Tiebreaker daha erken bir cevaptı.

(Dize, toroidal sınır koşulları ile sarılmadığını unutmayın .)

Örnekler

1) Bu giriş dizgisi 3 yola bağlı bölgeye (2 için 0ve 1 için 1) sahiptir. Yalnızca sağ alt 00bölge sağlam bir dikdörtgen olsa da, sonuç yanlış olur.

0011
0111
0100

2) Bu giriş dizgisi 4 yola bağlı bölgeye sahiptir (her ikisi için de 2 0ve 1). Hepsi sağlam dikdörtgenler, bu yüzden çıktı çok garip olurdu.

0011
0011
1100

3) Bu giriş 2 yola bağlı bölgeye sahiptir, ancak bunlardan sadece bir tanesi katı bir dikdörtgendir, bu nedenle çıktı yanlış olur.

00000000
01111110
00000000

4) Bu giriş sadece 1 yola bağlı bölgeye sahiptir ve temelde sağlam bir dikdörtgendir, bu nedenle çıktı truthy'dir.

11111111
11111111
11111111

Test Kılıfları

Bir Tsadece Giriş dizesi araçları truthy altında, Faraçlar 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

Yanıtlar:


5

Jöle , 7 bayt

ṣ⁷µ=ḢZE

Bu, @ LevelRiverSt'in Ruby cevabı ile aynı algoritmayı kullanır . Gerçek algoritma son 4 bayta sığar; giriş biçimini ayrıştırmak için ilk 3 bayt gerekir.

Çevrimiçi deneyin!

Nasıl çalışır

ṣ⁷µ=Ḣ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

Jöle , 11 10 bayt

ṣ⁷^2\⁺€FS¬

Bunun orjinal boyutunun yarısına kadar golf oynamak için @Dennis'e teşekkür ederiz (belgesiz özellikler ile).

Çevrimiçi deneyin ! Üçlü tırnakların çok satırlı bir dize için olduğuna dikkat edin.

açıklama

Temel algoritma şudur: her 2x2 alt-ızgarasının çift sayısı 1s (veya eşdeğerde 0s) olduğunda true döndürün.

Aşağıdakilerden birine sahip olacağımızdan, tek sayıdaki sayıların neden işe yaramadığı açık.

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

İlk 4'ün aynı şeyin dönmesi olduğuna ve son 4 için aynı olduğuna dikkat edin. Refleks açısı bir dikdörtgenin parçası olamaz, bu nedenle geçersiz sayılır.

Başka bir deyişle, tüm 2x2 alt dizinleri aşağıdakilerden biri olmalıdır:

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

Bu, sınırlara bakarsak, aşağıdaki "yapboz parçaları" olarak hayal edilebilir:

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

Ve bu yapboz parçalarıyla dikdörtgen olmayan bir şekil oluşturmayı deneyin :) (uçları eşleşirken)

Böylece gerçek uygulama:

ṣ⁷               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

Örneğin, giriş için

100
010
000
101

sahibiz:

  ṣ⁷: ["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
Lütfen kullandığınız özellikleri belgelendirebilir misiniz? Eğer insanlar bunu yaparsa dokümantasyon gerçekleşecek!
CalculatorFeline

Düzleştirmen gerekiyor mu?
CalculatorFeline

@CatsAreFluffy Eğer düzleşmezseniz, Jelly vektörlerin bir listesini toplamaya çalışır ve sonuç olarak bir vektör elde edersiniz
Sp3000

Sadece topla ve topla - daha iyi!
CalculatorFeline

4
"Belgelenmemiş özellikler" - aha! Yani o yıllardan nasıl Dennis'in outgolfs herkese! : D
AdmBorkBork

12

Ruby, 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}

Tamamen dikdörtgenlerden oluşan herhangi bir ızgarada, her bir satır önceki çizgiyle aynı olmalı veya tüm bitlerin 0'dan 1'e ters çevrilmesi ve tam tersi olmalıdır.

Bunu kanıtlaması kolaydır. Bir kağıt parçasını alın ve boydan boya dikey ve yatay çizgiler çizin. Şimdi dikdörtgenleri sadece 2 renk kullanarak renklendirin. Her çizgide tüm renklerin çevrildiği, çarpık bir dama tahtası olacak.

Çizgili dikdörtgenleri çizmek ister misiniz? satırlarınızdan herhangi birinin bir bölümünü silmeyi deneyin. Şimdi tasarımınızı renklendirmek için 2'den fazla renge ihtiyacınız olacak, çünkü 3 dikdörtgenin birleştiği noktalara (2 köşe ve kenar) sahip olacaksınız.

Şimdiye kadarki cevapların farkında olmadığına şaşırdım.

Bu algoritmanın başka bir dilde çok daha kısa olması gerektiğini düşünüyorum.

Test programında Ungolfed

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

Bahse girerim s.scan(/^?.*\n/)baytları kurtarmaya yardımcı olur.
Charles

3

Salyangoz , 20 bayt

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

3 sıfır, 2 veya 02 kare olan bir 2x2 kare yoksa ve sıfır veya sıfır olan bir veya 2x2 kare varsa , ızgara alanını yazdırır .


3

MATL , 12 bayt

Ybc2thYCs2\~

@ Sp3000'in mükemmel cevabıyla aynı algoritma .

Çok satırlı girişe izin vermek için MATL satır karakter dizisinin (string) 10newline için karakter kullanılarak açıkça oluşturulmasına ihtiyaç duyar . Yani dört örneğin girişi ( []birleştirme olduğuna dikkat edin , bu nedenle bunların her biri bir satır dizisidir):

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

ve son üç test durumu

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

Truthy çıkışı, sadece olanlar içeren bir dizidir.

Çevrimiçi deneyin!

açıklama

Bu karakterlerin paritesi gerçeğini kullanır '0've '1'sayıların aynıdır 0ve 1bu yüzden temsil haneli char dönüştürmek için orada ihtiyaç değil,

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

Girişin bir dize olması gerekiyor
Calvin'in Hobileri

@HelkaHomba MATL, çok satırlı dize girişine izin vermiyor ... Giriş ['first line' 10 'second llne'], 10yeni satır için ASCII olan formun bir satır dizisi olması gerekir . Bu kabul edilebilir mi?
Luis Mendo

@HelkaHomba Bunu güncellenmiş yanıtta kullandım. Alternatif olarak, yeni satır yerine boşluk kullanılabilir mi? İlk örnek string olacaktır'0011 0111 0100'
Luis Mendo

@LuisMendo Düşünceyi takdir ediyorum, ama Ruby'nin cevabının genel olarak burada daha golf oynayabileceğini düşünüyorum :)
Sp3000

@ Sp3000 Oh, bunu görmemiştim. Çok zekice
Luis Mendo

2

JavaScript (ES6), 69 bayt

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

Yola bağlı dikdörtgenin ölçütünün, isteğe bağlı bir dikdörtgenin köşelerini oluşturan dört noktanın, eşit sayıda 1s olmasını istemekle eşdeğer olduğuna inanıyorum . Dikdörtgenin paritesinin (0, b), (x, y) (0, b), (a, y) ^(a, b), (x, y) ile aynı olduğuna dikkat edin, sol üst köşesi (0, 0) olan dikdörtgenler. Ayrıca De Morgan yasalarına göre, !.some()aynı.every(!) beni birkaç bayttan kurtardığı .

Düzenleme: Jelly çözümünün, eşdeğer olduğu gösterilen tüm 2 × 2 dikdörtgenlerin köşelerinin eşliğini kontrol ettiğini fark ettim.


neredeyse 7 kez, ancak +1
edc65

2

JavaScript (ES6), 79

Aynı Jelly algoritması @ Sp3000'den yanıtlar (ve işe yaradığını ispat etmekten mutlu olmaz). Sadece 8 kat daha uzun

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

Daha az golf oynadı

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
   ) 

Test odası

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
Şimdi 8 kat daha uzun!
Neil

1

Grime v0.1, 31 bayt

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

Eşleşme 1için ve 0eşleşme olmadan yazdırır . Çevrimiçi deneyin!

açıklama

Grime benim 2B kalıp eşleştirme dilimim. Bugün değiştirdim, ancak yalnızca bir sözdizimi öğesinin karakterini ( `yerine ,) değiştirmek için puanımı etkilemiyor.

I edilene benzer bir yaklaşım kullanıyorum SP3000 : kimin bir satır maddeleri ihtiva eden 2 x N dikdörtgen içeriyorsa bir giriş falsy olan 0ve 1ve diğer satır değildir.

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 bayt

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

@ LevelRiverSt'in her bir hattın aynı olması veya ilkinin zıddı olması gerektiği yönündeki gözlemine dayanarak.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.