Untuk menemukan pulau 1 dan 0 dalam matriks

29

Diberikan matriks dua dimensi 0 dan 1. Temukan jumlah pulau untuk 1s dan 0s di mana tetangga hanya berada dalam posisi horizontal dan vertikal.

Given input:

1 1 1 0
1 1 1 0

output = 1 1
Number of 1s island = 1

xxx-
xxx-

Number of 0s island = 1 

---x
---x

------------------------------

Given input:

0 0 0 0
1 1 1 1
0 0 0 0
1 1 1 1

output = 2 2
Number of 1s island = 2

----
xxxx  <-- an island of 1s
----
xxxx  <-- another island of 1s

Number of 0s island = 2

xxxx  <-- an island
----
xxxx  <-- another island
----

------------------------------

Given input:

1 0 0
0 0 0
0 0 1
output = 2 1
Number for 1's island = 2:

x--  <-- an island of 1s
---
--x  <-- an island of 1s

Number of 0's island = 1:

-xx  \
xxx   > 1 big island of 0s
xx-  / 


------------------------------

Given input:

1 1 0
1 0 0
output = 1 1
Number for 1's island =1 and number of 0's island = 1

------------------------------

Given input:

1 1
1 1
output = 1 0
Number for 1's island =1 and number of 0's island = 0
KB sukacita
sumber
11
Anda harus menambahkan testcase ingin [[1,0];[0,1]]memastikan konektivitas diagonal tidak termasuk
Sanchises
8
Saya menyarankan output bisa dalam urutan apa pun selama pesanan tersebut ditentukan - itu tidak menambah nilai untuk memaksakan pesanan
streetster
8
Selamat datang di situs ini!
Arnauld
1
Apa yang dijawab dalam komentar harus diklarifikasi dalam tubuh tantangan. Dan lebih khusus lagi, jika Anda benar-benar ingin kami mengembalikan 1 sebelum 0, itu harus dinyatakan dengan jelas.
Arnauld
4
11111 / 10001 / 10101 / 10001 / 111112 1
Case

Jawaban:

16

APL (Dyalog Unicode) , 29 28 byte SBCS

-1 terima kasih kepada @ Adám

{≢∪∨.∧⍨⍣≡2>+/↑|∘.-⍨⍸⍵}¨⊂,~∘⊂

Cobalah online!

⊂,~∘⊂ matriks dan negasinya

{ untuk masing-masing dari mereka

⍸⍵ daftar pasangan 1s

+/↑|∘.-⍨ matriks jarak manhattan

2> matriks tetangga

∨.∧⍨⍣≡ penutupan transitif

≢∪ jumlah baris unik

ngn
sumber
ini sangat pintar. bisa Anda jelaskan mengapa baris terakhir dijamin bekerja - yaitu, mengapa baris unik setara dengan jawabannya. juga, apakah "penutupan transitif" sama dengan J ^:_?
Jonah
1
@Jonah lihat obrolan
ngn
16

J , 57 byte

,&([:(0#@-.~~.@,)](*@[*[:>./((,-)#:i.3)|.!.0])^:_ i.@$)-.

Cobalah online!

Ini adalah salah satu di mana idenya sangat sederhana (dan saya pikir menyenangkan), tetapi mengeksekusinya memiliki panjang mekanik yang menutupi kesederhanaan ... misalnya, menggeser matriks asli ke segala arah dengan 0 fill adalah verbose ((,-)#:i.3) |.!.0.

Kemungkinan panjang mekanik ini dapat di-golf lebih lanjut, dan saya dapat mencoba besok malam, tetapi saya akan memposting inti masalahnya sekarang.

Katakan input kami adalah:

0 0 0 0
1 1 1 1
0 0 0 0
1 1 1 1

Kita mulai dengan matriks bilangan bulat unik dengan ukuran yang sama:

 0  1  2  3
 4  5  6  7
 8  9 10 11
12 13 14 15

Kemudian untuk setiap sel kita menemukan maks semua tetangganya, dan dikalikan dengan topeng input:

 0  0  0  0
 8  9 10 11
 0  0  0  0
13 14 15 15

Kami mengulangi proses ini sampai matriks berhenti berubah:

 0  0  0  0
11 11 11 11
 0  0  0  0
15 15 15 15

Dan kemudian hitung jumlah elemen unik, bukan nol. Itu memberitahu kita jumlah 1-pulau.

Kami menerapkan proses yang sama untuk "1 minus input" untuk mendapatkan jumlah 0-pulau.

Jonah
sumber
3
Ini sangat mirip mekanisme "mengisi banjir", sangat rapi.
Matthieu M.
7

JavaScript (ES7),  138 ... 107  106 byte

Mengembalikan array [ones, zeros].

f=(m,X,Y,V=.5,c=[0,0])=>m.map((r,y)=>r.map((v,x)=>V-v|(x-X)**2+(y-Y)**2>1||f(m,x,y,v,r[c[v^1]++,x]=2)))&&c

Cobalah online!

Bagaimana?

Kami menggunakan fungsi rekursif. Selama panggilan awal, kami mencari 0 dan 1 . Setiap kali kami menemukan titik awal seperti itu, kami menambah penghitung pulau yang sesuai ( c[0] atau c[1] ) dan memasuki fase rekursif untuk mengisi area sel yang berdekatan yang serupa dengan 2 's.

Untuk menyimpan byte, kode yang sama persis digunakan untuk iterasi root dan iterasi rekursif, tetapi berperilaku sedikit berbeda.

Selama iterasi pertama:

  • V=0,5V-v0v=0v=1
  • XY(x-X)2+(y-Y)2mengevaluasi ke NaN . Ini memaksa tes ketimpangan gagal, tidak peduli nilainya(x,y).

Selama iterasi rekursif:

  • Parameter c diatur ke integer (2) bukannya array. Karena angka adalah objek di JS, ekspresi c[v ^ 1]++ini valid jikacadalah angka - meskipun tidak memiliki efek sama sekali. Ini berarti bahwa kita dapat menjalankan pernyataan ini tanpa syarat, tanpa mengetahui apakah kita sedang mencari titik awal atau mengisi banjir.

Berkomentar

f = (                 // f is a recursive function taking:
  m,                  //   m[]  = input binary matrix
  X, Y,               //   X, Y = coordinates of the previous cell, initially undefined
  V = .5,             //   V    = value of the previous cell, initially set to 0.5
                      //          so that the integer part of V - v is 0 for v = 0 or 1
  c = [0, 0]          //   c[]  = array of counters of 1's and 0's islands
) =>                  //          (or an integer when called recursively)
  m.map((r, y) =>     // for each row r[] at position y in m[]:
    r.map((v, x) =>   //   for each value v at position x in r[]:
      V - v |         //     abort if |V - v| ≥ 1
      (x - X) ** 2 +  //     or X and Y are defined and the quadrance between
      (y - Y) ** 2    //     (X, Y) and (x, y)
      > 1 ||          //     is greater than 1
      f(              //     otherwise, do a recursive call to f:
        m,            //       leave m[] unchanged
        x, y,         //       pass the new coordinates
        v,            //       pass the new reference value
        r[c[v ^ 1]++, //       increment c[v ^ 1] (ineffective if c is an integer)
          x           //       and set the current cell ...
        ] = 2         //       ... to 2
      )               //     end of recursive call
    )                 //   end of inner map()
  ) && c              // end of outer map(); return c
Arnauld
sumber
Kode ini tidak berfungsi untuk matriks besar seperti 100 * 100, dengan hanya 1s atau 0s karena stack overflow.
KB joy
3
@KBjoy Kecuali secara khusus ditentukan lain dalam tantangan, aturan default kami adalah bahwa kami tidak peduli tentang batasan implementasi selama algoritma yang mendasarinya bekerja secara teori untuk input apa pun. ( Berikut ini adalah pos meta tentang itu, tetapi mungkin ada yang lebih relevan di suatu tempat.)
Arnauld
7

MATL , 14 12 byte

,G@-K&1ZIugs

Cobalah online! Atau verifikasi semua kasus uji .

Penjelasan

,        % Do twice
  G      %   Push input
  @      %   Push iteration index: first 0, then 1
  -      %   Subtract. This converts 0 and 1 into -1 and 0 in the second iteration 
  K      %   Push 4
  &1ZI   %   Label connected components of matrix using 4-connectedness. Zeros in the
         %   matrix are background. This replaces the nonzeros by 1, 2, 3, ..., where 
         %   each number defines a connected component
  u      %   Unique values. This gives [0; 1; 2; ..., L], where L is the number of
         %   connected components.
  g      %   Convert nonzeros to 1
  s      %   Sum. This gives L, to be output
         % End (implicit).
         % Display stack (implicit)
Luis Mendo
sumber
6

K (ngn / k) , 60 55 51 50 46 byte

{#?{|/'x*\:x}/2>+/x*x:x-\:'x:(0,#*x)\&,/x}'~:\

Cobalah online!

~:\ sepasang input dan negasinya (secara harfiah: negate iterate-konvergen)

{ }' untuk setiap

,/x ratakan arg

&dimana 1s? - daftar indeks

(0,#*x)\ lebar divmod (input) untuk mendapatkan dua daftar terpisah untuk ys dan xs

x-\:'x: jarak per-sumbu ∆x dan ∆y

x*x: persegi mereka

+/ tambahkan ∆x² dan ∆y²

2> matriks tetangga

{|/'x*\:x}/ penutupan transitif

#? hitung baris unik

ngn
sumber
Setelah melihat jawaban Anda, saya senang saya tidak mencoba untuk mengatasi ini di K :)
streetster
2
@streetster haha, terima kasih! itu bukan efek yang saya maksudkan :) saya sebenarnya ingin mendorong orang untuk belajar (dialek apa pun) k dan golf di dalamnya
ngn
6

Bahasa Wolfram (Mathematica) , 64 62 byte

Max@MorphologicalComponents[#,CornerNeighbors->1<0]&/@{#,1-#}&

Cobalah online!

Berkat attinat : kita bisa menulis 1<0alih-alihFalse dan menyimpan dua byte.

versi tidak golf:

F[M_] := {Max[MorphologicalComponents[M,   CornerNeighbors -> False]], 
          Max[MorphologicalComponents[1-M, CornerNeighbors -> False]]}

Ada, tentu saja, sebuah Mathematica builtin MorphologicalComponentsyang mengambil array (atau gambar) dan mengembalikan yang sama dengan piksel setiap pulau yang terhubung secara morfologis digantikan oleh indeks pulau. Mengambil Maxdari hasil ini memberikan jumlah pulau (nol latar belakang dibiarkan nol, dan indeks pulau dimulai pada 1). Kita perlu melakukan ini secara terpisah untuk array (memberikan jumlah 1-pulau) dan satu minus array (memberikan jumlah 0-pulau). Untuk memastikan tetangga diagonal tidak dihitung sebagai tetangga, opsi CornerNeighbors->Falseharus diberikan.

Roma
sumber
-2 byte karena ketidaksetaraan memiliki prioritas lebih tinggi daripadaRule
attinat
5

Python 3, 144 127 byte

Solusi ini menggunakan cv2kekuatan pemrosesan gambar yang luar biasa. Meskipun nama metode cv kurang mengagumkan, super panjang dan mudah dibaca, ini mengalahkan kedua jawaban Python lainnya!

Golf:

import cv2,numpy as n
f=lambda b:n.amax(cv2.connectedComponents(b*255,0,4)[1])
def g(a):b=n.array(a,n.uint8);print(f(1-b),f(b))

Diperluas:

import cv2
import numpy as np

# Finds the number of connected 1 regions 
def get_components(binary_map):
    _, labels = cv2.connectedComponents(binary_map*255, connectivity=4) # default connectivity is 8
    # labels is a 2d array of the binary map but with 0, 1, 2, etc. marking the connected regions
    components = np.amax(labels)
    return components

# Takes a 2d array of 0s and 1s and returns the number of connected regions
def solve(array): 
    binary_map = np.array(input_map, dtype=np.uint8)
    black_regions = get_components(1 - binary_map) # 0s
    white_regions = get_components(binary_map) # 1s
    return (black_regions, white_regions)
Daniel
sumber
Saya tidak terlalu terbiasa dengan Python, tetapi mengapa Anda membutuhkan nama argumen eksplisit? Bukankah hanya 4bukannya connectivity=4dan n.uint8bukannya dtype=n.uint8mungkin?
Kevin Cruijssen
@KevinCruijssen, Anda memerlukan nama argumen jika Anda melewatkan argumen opsional. Mengintip dokumen, saya sebenarnya tidak perlu melewatkan, yang menyelamatkan saya banyak byte. Terima kasih!
Daniel
Ah ok, saya pikir itu seperti itu, tetapi ketika saya hanya melihat dokumen saya hanya bisa menemukan satu cv2.connectedComponentsmetode, jadi saya bingung dan berpikir mungkin ada alasan berbeda untuk memerlukan nama argumen. Seperti yang saya katakan, saya tidak terlalu terbiasa dengan Python. Yang saya pelajari darinya adalah dari sini di CCGC. ;) Tetapi masuk akal untuk menggunakan nama variabel untuk melewati argumen opsional lainnya.
Kevin Cruijssen
1
Sangat bagus! Saya menemukan kompiler online yang mencakup modul cv2 di sini .
Jitse
5

J , 46 44 43 byte

-1 byte terima kasih kepada @miles

,&#&~.&([:+./ .*~^:_:2>1#.[:|@-"1/~4$.$.)-.

Cobalah online!

tes dan ,& -.bungkusnya dicuri dari jawaban @ jonah

,& -. untuk input dan negasinya lakukan:

4$.$. (y, x) koordinat 1s sebagai matriks n × 2

1#.[:|@-"1/~ jarak manhattan: abs (∆x) + abs (∆y)

2> matriks tetangga

[:+./ .*~^:_: penutupan transitif

#&~.&( ) jumlah baris unik

ngn
sumber
1
Anda dapat membuat panjang dan unik untuk menyimpan byte lain, yaitu ,&#&~.untuk menghindari tutup[:
mil
@miles terima kasih
ngn
3

Retina 0.8.2 , 155 byte

s`1(.*)
;$1a
}+`(?<=(.)*)(1|;)(.*¶(?<-1>.)*(?(1)$))?(?!\2)[1;]
;$3;
s`0(.*)
:$1b
}+`(?<=(.)*)(0|:)(.*¶(?<-1>.)*(?(1)$))?(?!\2)[0:]
:$3:
\W+(a*)(b*)
$.1 $.2

Cobalah online! Tautan termasuk test case. Penjelasan:

s`1(.*)
;$1a

Jika ada 1, ubah ke ;dan tambahkan ake akhir input sehingga tidak menghalangi.

}+`(?<=(.)*)(1|;)(.*¶(?<-1>.)*(?(1)$))?(?!\2)[1;]
;$3;

Banjir mengisi lagi yang berdekatan 1 dengan ;s.

}

Ulangi sampai semua pulau 1telah berubah menjadi; .

s`0(.*)
:$1b

Jika ada 0, ubah ke :dan tambahkan ab ke akhir input sehingga tidak menghalangi.

+`(?<=(.)*)(0|:)(.*¶(?<-1>.)*(?(1)$))?(?!\2)[0:]
:$3:

Isi banjir lagi bersebelahan 0dengan:s.

}

Ulangi sampai semua pulau 0telah berubah menjadi: .

\W+(a*)(b*)
$.1 $.2

Hitung secara terpisah jumlah pulau 1s dan 0s.

Neil
sumber
3

Haskell , 228 227 225 224 byte

import Data.List
z=zipWith
a!b=div(max(a*a)(a*b))a
l x=z(!)(z(!)x(0:x))$tail x++[0]
s=(\x->length.($x).filter<$>[(>0),(<0)]).nub.(>>=id).(until=<<((==)=<<))((.)>>=id$transpose.map l).z(\i->z(\j x->2^i*j*(2*x-1))[1,3..])[1..]

Cobalah online!

Penjelasan:

Gagasan untuk solusi ini adalah sebagai berikut: Menginisialisasi matriks dengan nilai unik di setiap sel, positif untuk 1dan negatif untuk 0. Kemudian berulang kali membandingkan setiap sel dengan tetangganya dan, jika tetangganya memiliki tanda yang sama tetapi nomor dengan nilai absolut yang lebih besar, ganti nomor sel dengan nomor tetangga. Setelah ini mencapai titik tetap, hitung jumlah angka positif berbeda untuk jumlah 1wilayah dan angka negatif berbeda untuk jumlah0 wilayah.

Dalam kode:

s=(\x->length.($x).filter<$>[(>0),(<0)]).nub.(>>=id).(until=<<((==)=<<))((.)>>=id$transpose.map l).z(\i->z(\j x->2^i*j*(2*x-1))[1,3..])[1..]

dapat dipisahkan menjadi preprocessing (menetapkan angka ke sel), iterasi, dan postprocessing (menghitung sel)

Preprocessing

Bagian preprocessing adalah fungsinya

z(\i->z(\j x->2^i*j*(2*x-1))[1,3..])[1..]

Yang digunakan zsebagai singkatan untuk zipWithmencukur beberapa byte. Apa yang kita lakukan di sini adalah zip array dua dimensi dengan indeks integer di baris dan indeks integer ganjil di kolom. Kami melakukan ini karena kami dapat membangun bilangan bulat unik dari sepasang bilangan bulat (i,j)menggunakan rumus (2^i)*(2j+1). Jika kami hanya menghasilkan bilangan bulat ganjil untuk j, kami dapat melewati penghitungan2*j+1 , menghemat tiga byte.

Dengan nomor unik, kita sekarang hanya perlu mengalikan tanda berdasarkan nilai dalam matriks, yang diperoleh sebagai 2*x-1

Perulangan

Iterasi dilakukan oleh

(until=<<((==)=<<))((.)>>=id$transpose.map l)

Karena inputnya dalam bentuk daftar daftar, kami melakukan perbandingan tetangga pada setiap baris, mengubah matriks, melakukan perbandingan pada setiap baris lagi (yang karena transpose adalah apa yang menjadi kolom sebelumnya) dan mentranspos lagi. Kode yang menyelesaikan salah satu dari langkah-langkah ini adalah

((.)>>=id$transpose.map l)

di mana lfungsi perbandingan (dirinci di bawah) dan transpose.map lmelakukan setengah dari langkah perbandingan dan transposisi. (.)>>=idmelakukan argumennya dua kali, menjadi bentuk pointfree \f -> f.fdan lebih pendek satu byte dalam hal ini karena aturan prioritas operator.

ldidefinisikan pada baris di atas sebagai l x=z(!)(z(!)x(0:x))$tail x++[0]. Kode ini melakukan operator pembanding (!)(lihat di bawah) pada setiap sel dengan tetangga sebelah kiri pertama, dan kemudian dengan tetangga kanannya, dengan zip daftar xdengan daftar bergeser kanan dan bergeser daftar 0:xkiri tail x++[0]pada gilirannya. Kami menggunakan nol untuk membuat daftar bergeser, karena mereka tidak pernah dapat terjadi dalam matriks yang telah diproses.

a!bdidefinisikan pada baris di atas ini sebagai a!b=div(max(a*a)(a*b))a. Yang ingin kami lakukan di sini adalah perbedaan kasus berikut:

  • Jika sgn(a) = -sgn(b), kami memiliki dua bidang yang berlawanan dalam matriks dan tidak ingin menyatukannya, jadi atetaplah tidak berubah
  • Jika sgn(b) = 0, kami memiliki kasing sudut di mana bbantalan dan oleh karena itu atetap tidak berubah
  • Jika sgn(a) = sgn(b), kami ingin menyatukan dua area dan mengambil satu dengan nilai absolut yang lebih besar (demi kenyamanan).

Catatan yang sgn(a)tidak pernah bisa 0. Kami mencapai ini dengan formula yang diberikan. Jika tanda-tanda adan bberbeda, a*bkurang atau sama dengan nol, sementara a*aselalu lebih besar dari nol, maka kami memilihnya sebagai maksimum dan membaginya dengan auntuk kembali a. Jika tidak, max(a*a)(a*b)adalah abs(a)*max(abs(a),(abs(b)), dan dengan membagi ini dengan a, kita dapatkan sgn(a)*max(abs(a),abs(b)), yang merupakan angka dengan nilai absolut yang lebih besar.

Untuk beralih fungsi ((.)>>=id$transpose.map l)sampai mencapai titik tetap, kami menggunakan (until=<<((==)=<<)), yang diambil dari jawaban stackoverflow ini .

Pengolahan pasca

Untuk postprocessing, kami menggunakan bagian itu

(\x->length.($x).filter<$>[(>0),(<0)]).nub.(>>=id)

yang hanya kumpulan langkah-langkah.

(>>=id)remas daftar daftar menjadi satu daftar, nubsingkirkan ganda, pisahkan (\x->length.($x).filter<$>[(>0),(<0)])daftar menjadi sepasang daftar, satu untuk bilangan positif dan satu untuk bilangan negatif, dan hitung panjangnya.

Sacchan
sumber
2

Java 10, 359 355 281 280 261 246 byte

int[][]M;m->{int c[]={0,0},i=m.length,j,t;for(M=m;i-->0;)for(j=m[i].length;j-->0;)if((t=M[i][j])<2)c[t^1]+=f(t,i,j);return c;}int f(int v,int x,int y){try{if(M[x][y]==v){M[x][y]|=2;f(v,x+1,y);f(v,x,y+1);f(v,x-1,y);f(v,x,y-1);}}finally{return 1;}}

-74 byte terima kasih kepada @NahuelFouilleul .

Cobalah online.

Penjelasan:

int[][]M;              // Integer-matrix on class-level, uninitialized

m->{                   // Method with integer-matrix parameter and integer-array return-type
  int c[]={0,0}        //  Counters for the islands of 1s/0s, starting both at 0
      i=m.length,      //  Index of the rows
      j,               //  Index of the columns
      t;               //  Temp-value to decrease the byte-count
  for(M=m;             //  Set the class-level matrix to the input-matrix
      i-->0;)          //  Loop over the rows
    for(j=m[i].length;j-->0)
                       //   Inner loop over the columns
      if((t=M[i][j])   //    Set the temp value `t` to the value of the current cell
         <2)           //    And if this value is a 0 or 1:
        c[t^1]+=       //     Increase the corresponding counter by:
          f(t,i,j);    //      Call the recursive flood-fill method with value `t`
                       //      Which always returns 1 to increase the counter
  return c;}           //  After the nested loops: return the counters-array as result

// Recursive method with value and cell-coordinate as parameters,
// This method will flood-fill the matrix, where 0 becomes 2 and 1 becomes 3
int f(int v,int x,int y){
  try{if(M[x][y]==v){  //   If the cell contains the given value:
    M[x][y]|=2;        //    Fill the cell with 0→2 or 1→3 depending on the value
    f(v,x+1,y);        //    Do a recursive call downwards
    f(v,x,y+1);        //    Do a recursive call towards the right
    f(v,x-1,y);        //    Do a recursive call upwards
    f(v,x,y-1);}       //    Do a recursive call towards the left
  }finally{return 1;}} //  Ignore any ArrayIndexOutOfBoundsExceptions with a finally-return,
                       //  which is shorter than manual checks
                       //  And return 1 to increase the counter
Kevin Cruijssen
sumber
1
-74 byte , menghapus clone dan menggunakan |=2: 0 -> 2 dan 1 -> 3, namun>0 diubah menjadi==1
Nahuel Fouilleul
maaf saya harus menghapus tes sehingga tautan tio sesuai dengan komentar
Nahuel Fouilleul
@NahuelFouilleul Terima kasih, pintar menggunakan |=2! Dan saya masih bisa menggunakan<2 bukan ==1untuk -1 byte dengan terlebih dahulu memeriksa 0(dan dengan demikian mereka diubah menjadi 2, dan kemudian menggunakan <2untuk memeriksa 1(yang diubah menjadi 3)
Kevin Cruijssen
2

Python 3 , 167 byte

def f(m):
 n=[0,0];i=-2
 for r in m:
  j=0;i+=1
  for c in r:n[c^1]+=1-((i>=0)*(m[i][j]==c)*(1+({*r[:j]}=={c})*({*m[i][:j]}=={c^1}))or(j>0)*(r[j-1]==c));j+=1
 print(n)

Cobalah online!


Python 2 , 168 byte

def f(m):
 n=[0,0];i=-2
 for r in m:
	j=0;i+=1
	for c in r:n[c^1]+=1-((i>=0)*(m[i][j]==c)*(1+(set(r[:j])=={c})*(set(m[i][:j])=={c^1}))or(j>0)*(r[j-1]==c));j+=1
 print n

Cobalah online!

-2 byte terima kasih kepada Kevin Cruijssen

Perbaikan pemformatan +2 byte

Penjelasan

Penghitung disimpan untuk 0s dan 1s. Untuk setiap entri dalam matriks, tindakan berikut dilakukan:

  • Menambahkan penghitung untuk nilai saat ini dengan 1
  • Jika nilai yang sama ada tepat di atas atau ke kiri, kurangi sebesar 1

Ini menghasilkan false positive untuk kasus rata kiri seperti

0 0 1
1 1 1

atau

0 1
1 1

Jika situasi seperti itu muncul, penghitung berkurang sebesar 1.

Nilai pengembalian adalah [#1, #0]

Jitse
sumber
1
Saya khawatir OP disebutkan dalam komentar kedua urutan seharusnya [#1, #0]. Agak tidak ada gunanya untuk menegakkan ini, tetapi untuk sekarang ini adalah apa adanya. Pokoknya, Anda bisa bermain golf {not c}untuk {c^1}, dan memperbaiki masalah yang saya sebutkan dengan mengubah n[c]+=ke n[c^1]+=dalam masalah yang sama. Jawaban yang bagus, +1 dari saya. :)
Kevin Cruijssen
Ah kamu benar Terima kasih!
Jitse
1

Perl 5 ( -0777p), 110 byte

Mungkin ditingkatkan, menggunakan regex untuk mengganti 1dengan 3, kemudian 0dengan 2.

/
/;$m="(.{@-})?";sub f{($a,$b,$c)=@_;1while s/$b$m\K$a|$a(?=$m$b)/$b/s||s/$a/$b/&&++$c;$c}$_=f(1,3).$".f(0,2)

TIO

Nahuel Fouilleul
sumber
1

Jelly , 44 36 byte

ŒJfⱮ+€¥Ø.,UŻ¤œịƇþ,¬$¹ƇfƇⱮ`ẎQ$€QƲÐL€Ẉ

Cobalah online!

Tautan monadik yang menerima daftar daftar bilangan bulat sebagai argumennya dan mengembalikan daftar jumlah pulau 1 dan 0 dalam urutan itu.

Penjelasan

Langkah 1

Hasilkan daftar semua indeks matriks masing-masing dengan indeks tetangganya ke kanan (kecuali di sisi kanan) dan ke bawah (kecuali di bagian bawah)

ŒJ            | Multi-dimensional indices (e.g. [1,1],[1,2],[1,3],[2,1],[2,2],[2,3])
      ¥       | Following as as a dyad:
  fⱮ          | - Filter the indices by each of:
    +€      ¤ |   - The indices added to the following
       Ø.     |     - 0,1
         ,U   |     - Paired with itself reversed [0,1],[1,0]
           Ż  |     - Prepended with zero 0,[0,1],[1,0]

Langkah 2

Pisahkan indeks ini dengan apakah ada 1 atau 0 pada input. Mengembalikan satu daftar indeks dengan tetangga untuk 1 dan yang lain untuk 0.

  Ƈþ   | Filter each member of the output of stage 1 using the following criteria:
œị   $ | - Corresponding value for the multi-dimensional indices in each of the following as a monad:
   ,¬  |   - The input paired with its inverse

Langkah 3

Gabungkan daftar dengan anggota dalam jumlah yang sama dan hasil

           ƲÐL€  | For each of the outputs from stage 2, do the following as a monad and repeat until no changes
¹Ƈ               | - Filter out empty lists (only needed on first pass through but included here to save a byte)         
  fƇⱮ`           | - Take each list of indices and filter the list of indices for those containing a match for any of them
        $€       | - For each resulting list of lists:
      Ẏ          |   - Tighten (concatenate top level of lists)
       Q         |   - Uniquify
          Q      | - Uniquify
               Ẉ | Finally output the lengths of the final lists
Nick Kennedy
sumber
1

T-SQL 2008, 178 byte

Input adalah variabel tabel.

x dan y adalah koordinatnya

v adalah nilai 0 dan 1 (bisa juga menangani nilai numerik lainnya)

Data uji yang digunakan dalam contoh ini:

100
000
001
DECLARE @ table(x int, y int, v int)

INSERT @ values
(1,1,1),(1,2,0),(1,3,0),
(2,1,0),(2,2,0),(2,3,0),
(3,1,0),(3,2,0),(3,3,1)
SELECT*,y-x*99r INTO # FROM @
WHILE @@rowcount>0UPDATE #
SET r=b.r
FROM #,# b
WHERE abs(#.x-b.x)+abs(#.y-b.y)=1and #.v=b.v and #.r>b.r
SELECT v,count(distinct r)FROM #
GROUP BY v

Cobalah online

t-clausen.dk
sumber
1

R , 194 172 byte

function(m,u=!1:2){for(i in 1:2){w=which(m==i-1,T)
N=1:nrow(w)
A=!!N
for(s in N){u[i]=u[i]+A[s]
while(any(s)){A[s]=F
s=c(N[as.matrix(dist(w))[s[1],]==1&A],s[-1])}}}
rev(u)}

Cobalah online!

Lakukan pencarian kedalaman-pertama yang dimulai pada setiap sel dari matriks yang sama dengan 1 (atau nol).

  • -2 byte terima kasih kepada @Giuseppe
menggali semua
sumber