行列で1と0の島を見つけるには


29

0と1の2次元行列が与えられます。隣人が水平および垂直のみにある1と0の島の数を見つけます。

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

11
[[1,0];[0,1]]対角線接続が含まれていないことを確認するようなテストケースを追加する必要があります
Sanchises

8
順序が指定されている限り、出力はどちらの順序でも構いません
ストリートスター

8
サイトへようこそ!
アーナウルド

1
コメントで回答された内容は、チャレンジの本文で明確にする必要があります。より具体的には、0の前に1を返すように本当にしたい場合は、それを明確に述べてください。
アーナウルド

4
推奨されるテストケース:11111 / 10001 / 10101 / 10001 / 111112 1
Kevin Cruijssen

回答:


16

APL(Dyalog Unicode)29 28バイトSBCS

-1 @Adámに感謝

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

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

⊂,~∘⊂ 行列とその否定

{ それらのそれぞれのために

⍸⍵ 1の座標のペアのリスト

+/↑|∘.-⍨ マンハッタン距離の行列

2> 隣接行列

∨.∧⍨⍣≡ 推移的閉鎖

≢∪ 一意の行の数


これは本当に賢いです。最終行が機能することが保証されている理由、つまり一意の行が答えと同等である理由について詳しく説明してください。また、「推移的閉包」はJのようなもの^:_ですか?
ヨナ

1
@ジョナはチャットを
ngn

16

J、57バイト

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

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

これは、アイデアが信じられないほどシンプル(そして楽しいと思う)の1つですが、それを実行すると、単純さを覆い隠す機械的な長さがありました。 ((,-)#:i.3) |.!.0

この機械的な長さはさらにゴルフできる可能性が高いので、明日の夜に試してみるかもしれませんが、今はその要点を投稿します。

入力は次のとおりです。

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

同じサイズの一意の整数の行列から始めます。

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

次に、各セルについて、そのすべての隣接セルの最大値を見つけ、入力マスクを掛けます:

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

マトリックスの変更が停止するまで、このプロセスを繰り返します。

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

そして、一意の非ゼロ要素の数をカウントします。1島の数がわかります。

同じプロセスを「1-入力」に適用して、0アイランドの数を取得します。


3
これは、「フラッドフィル」メカニズムに非常によく似ており、非常にきれいです。
マチューM.

7

JavaScript(ES7)、 138 ... 107  106バイト

配列を返します[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

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

どうやって?

再帰関数を使用します。最初の呼び出し中に、01を探します。そのような開始点を見つけるたびに、対応するアイランドカウンター(c[0]またはc[1])をインクリメントし、再帰フェーズに入り、同様の隣接セルの領域を2で塗りつぶします。2ます。

バイトを節約するために、ルート反復と再帰反復の両方でまったく同じコードが使用されますが、動作が少し異なります。

最初の反復中:

  • V=0.5Vv0v=0v=1
  • バツYバツバツ2+yY2バツy

再帰反復中:

  • c2c[v ^ 1]++cが数値のが、まったく効果はありません。つまり、現在開始点を探しているのか、それとも塗りつぶしを探しているのかを知らなくても、このステートメントを無条件に実行できるということです。

コメント済み

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

このコードは、スタックオーバーフローのために1または0だけの100 * 100のような大きな行列では機能しません。
KB joy

3
@KBjoyチャレンジで特に明示的に指定されていない限り、デフォルトのルールでは、入力に対して理論的に基礎となるアルゴリズムが機能している限り、実装の制限は気にしません。(これに関するメタ投稿がありますが、おそらくもっと関連性の高いものがどこかにあります。)
Arnauld

7

MATL14 12バイト

,G@-K&1ZIugs

オンラインでお試しください!または、すべてのテストケースを確認します

説明

,        % 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)

6

K(ngn / k)60 55 51 50 46バイト

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

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

~:\ 入力とその否定のペア(文字通り:iterate-convergeの否定)

{ }' それぞれについて

,/x 引数を平坦化します

&1はどこですか?-インデックスのリスト

(0,#*x)\ divmod width(input)は、ysとxsの2つの個別のリストを取得します

x-\:'x: 軸ごとの距離∆xおよび∆y

x*x: それらを二乗する

+/ ∆x²と∆y²を追加します

2> 隣接行列

{|/'x*\:x}/ 推移的閉鎖

#? 一意の行をカウントする


あなたの答えを見た後、私はKでこれに取り組むことを試みなかったことをうれしく思います:)
ストリートスター

2
@streetsterハハ、ありがとう!それは私が意図した効果ではありません:)私は実際に人々にk(の方言)を学び、その中でゴルフをすることを奨励したいと思います
ngn

6

Wolfram言語(Mathematica)64 62バイト

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

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

attinatのおかげ1<0False、2バイトの代わりに書き込み、保存できます。

ゴルフされていないバージョン:

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

もちろん、配列(または画像)を受け取り、形態学的に接続された各島のピクセルを島のインデックスに置き換えて返すMathematica組み込み関数MorphologicalComponentsがあります。Maxこの結果を取得すると、島の数が得られます(背景のゼロはゼロのままになり、島のインデックスは1から始まります)。これを、配列(1島の数を与える)と1から配列(0島の数を与える)に対して別々に行う必要があります。対角線上の近傍が近傍としてカウントされないようにするには、オプションを指定CornerNeighbors->Falseする必要があります。


-2バイト不等式がより高い優先順位を有するのでRule
attinat

5

Python 3、144 127バイト

このソリューションはcv2の素晴らしい画像処理能力を使用しています。cvはそれほど素晴らしくなく、非常に長く読みやすいメソッド名ですが、Pythonの他の両方の答えに勝っています!

ゴルフ:

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))

拡張:

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)

私はPythonにあまり詳しくありませんが、なぜ明示的な引数名が必要なのですか?だけのものではありません4代わりに、connectivity=4n.uint8の代わりに、dtype=n.uint8可能?
ケビンクルーッセン

@KevinCruijssen、オプションの引数をスキップする場合は引数名が必要です。ドキュメントを覗いてみると、実際にスキップする必要はありません。これにより、多くのバイトを節約できます。ありがとう!
ダニエル

ああ、私はそれがそのようなものだと思ったが、ドキュメントを見たとき、私は単一のcv2.connectedComponentsメソッドしか見つけられなかったので、私は混乱し、引数名を必要とする別の理由があるかもしれないと思った。私が言ったように、私はPythonにあまり詳しくありません。ここから学んだことは、CCGCのここからです。;)しかし、変数名を使用して他のオプションの引数をスキップすることは理にかなっています。
ケビンクルーッセン

1
非常に素晴らしい!ここで cv2モジュールを含むオンラインコンパイラを見つけました。
Jitse

5

J 46 44 43バイト

@milesのおかげで-1バイト

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

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

@jonahの答え,& -.から盗まれたテストとラッパー

,& -. 入力とその否定のために:

4$.$. (y、x)nの2行列としての1の座標

1#.[:|@-"1/~ マンハッタン距離:abs(∆x)+ abs(∆y)

2> 隣接行列

[:+./ .*~^:_: 推移的閉鎖

#&~.&( ) 一意の行の数


1
長さを構成して、別のバイトを保存する、つまり,&#&~.上限を回避するために一意にすることができます[:
マイル

@milesありがとう
ngn

3

Retina 0.8.2、155バイト

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

オンラインでお試しください!リンクにはテストケースが含まれます。説明:

s`1(.*)
;$1a

がある場合1、それを変更し、入力の最後に;追加しaて、邪魔にならないようにします。

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

隣接するを1sで塗りつぶします;

}

すべての1s の島がsに変わるまで繰り返し;ます。

s`0(.*)
:$1b

がある場合0、それを変更し、入力の最後に:a bを追加して、邪魔にならないようにします。

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

隣接するを0sで塗りつぶします:

}

すべての0s の島がsに変わるまで繰り返し:ます。

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

1sと0sの島の数を別々に数えます。


3

Haskell228 227 225 224バイト

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..]

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

説明:

この解決策のアイデアは次のとおり1です0。各セルの一意の値で行列を初期化します。次に、各セルを隣接セルと繰り返し比較し、隣接セルの符号が同じで絶対値が大きい場合は、セルの番号を隣接する番号に置き換えます。これが固定小数点に達したら、1地域の数に対して明確な正の数の数を数え、地域の数に対して明確な負の数の数を数えます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..]

前処理(セルへの番号の割り当て)、反復、および後処理(セルのカウント)に分けることができます。

前処理

前処理部分は関数です

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

これは、数バイトを削るzための略語として使用しzipWithます。ここでは、行に整数のインデックスを、列に奇数の整数のインデックスを使用して2次元配列を圧縮します。これは(i,j)、式を使用して整数のペアから一意の整数を作成できるため(2^i)*(2j+1)です。に対して奇数の整数のみを生成する場合j、計算をスキップできます2*j+1 3バイトを節約ます。

一意の番号を使用すると、行列の値に基づいて符号を乗算するだけで済み、次のように取得されます 2*x-1

反復

繰り返しは

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

入力はリストの形式であるため、各行で近隣比較を実行し、行列を転置し、各行で比較を再実行します(転置は以前の列であったものです)、再び転置します。これらの手順のいずれかを実行するコードは

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

where lは比較関数(詳細は後述)でありtranspose.map l、比較および転置ステップの半分を実行します。(.)>>=id引数を2回実行します\f -> f.f。この場合、演算子の優先順位規則により、ポイントフリー形式で1バイト短くなります。

lは上の行でとして定義されていl x=z(!)(z(!)x(0:x))$tail x++[0]ます。このコードは(!)、リストxを右シフトリスト0:xと左シフトリストtail x++[0]で順番に圧縮することにより、最初に左隣、次に右隣のすべてのセルに対して比較演算子(以下を参照)を実行します。ゼロを使​​用して、シフトされたリストを埋め込みます。前処理された行列ではゼロは発生しないためです。

a!b上の行でとして定義されていa!b=div(max(a*a)(a*b))aます。ここでやりたいことは、次のケースの区別です。

  • の場合sgn(a) = -sgn(b)、マトリックスに2つの対向する領域があり、それらを統合したくないため、a変更されないままです。
  • の場合sgn(b) = 0bパディングであるため、a変更されないコーナーケースがあります
  • の場合sgn(a) = sgn(b)、2つの領域を統合し、絶対値が大きい方を使用します(便宜上)。

sgn(a)は決してできないことに注意してください0。与えられた式でこれを達成します。徴候場合ab異なるが、a*b小さいまたはゼロに等しく、一方では、a*a我々が最大と分割として選択ので、常にゼロよりも大きいaバック取得しますa。それ以外の場合、max(a*a)(a*b)abs(a)*max(abs(a),(abs(b))であり、これをaで除算すると、が得られますsgn(a)*max(abs(a),abs(b))。これは、より大きな絶対値を持つ数値です。

((.)>>=id$transpose.map l)固定小数点に達するまで関数を反復するに(until=<<((==)=<<))は、このstackoverflow answerから取得したを使用します

後処理

後処理には、パーツを使用します

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

これは単なる手順の集まりです。

(>>=id)リストのリストを単一のリストに nub押しつぶし、ダブルを取り除き (\x->length.($x).filter<$>[(>0),(<0)])、リストを正の数と負の数のリストのペアに分割し、それらの長さを計算します。


2

Java 10、359 355 281 280 261 246バイト

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;}}

@NahuelFouilleulに感謝-74バイト。

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

説明:

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

1
-74バイト、クローンの削除および使用|=2:0-> 2および1->3。ただし、次のよう>0に変更されました==1
Nahuel Fouilleul

申し訳ありませんが、tioリンクがコメントに収まるようにテストを削除する必要がありました
Nahuel Fouilleul

@NahuelFouilleulありがとう、スマート使用|=2!そして、-1バイトの<2代わりに==1、最初にチェックすることで使用できます0(したがって、に変更され2、次にを使用し<2てチェックします1(これはに変更されます3)。)
Kevin Cruijssen

2

Python 3、167バイト

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)

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


Python 2、168バイト

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

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

-2バイト、Kevin Cruijssenのおかげ

+2バイトのフォーマット修正

説明

カウンターは0と1の間保持されます。マトリックスの各エントリに対して、次のアクションが実行されます。

  • 現在の値のカウンターを1増やす
  • 同じ値が真上または左に存在する場合は、1ずつ減少します

これにより、次のような左寄せの場合に誤検出が発生します。

0 0 1
1 1 1

または

0 1
1 1

そのような状況が発生した場合、カウンターは1つ減少します。

戻り値は [#1, #0]


1
私は、2番目のコメントで言及されたOPが順序があるべきであると恐れています[#1, #0]。これを強制するのは少し無意味なですが、今のところそれが何であるかです。とにかく、{not c}to をゴルフして{c^1}、同様の問題でn[c]+=to n[c^1]+=に変更することで、私が言及した問題を修正できます。いい答えです、私から+1。:)
ケビン・クルーッセン

ああ、あなたは正しい。ありがとう!
Jitse

1

Perl 5(-0777p)、110バイト

向上させることができる、交換する正規表現使用1とし3、その後、02

/
/;$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


1

ゼリー44 36バイト

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

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

引数として整数のリストのリストを受け入れ、その順序で1および0の島の数のリストを返すモナドリンク。

説明

ステップ1

右側(右側にある場合を除く)と下方(底部にある場合を除く)に隣接するすべてのインデックスのリストを生成します。

Œ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]

ステップ2

入力に1または0があったかどうかでこれらのインデックスを分割します。1の近傍と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

ステップ3

リストを共通のメンバーと出力カウントにマージする

           ƲÐ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

1

T-SQL 2008、178バイト

入力はテーブル変数です。

xとyは座標です

vは値0および1です(他の数値も処理できます)

この例で使用されるテストデータ:

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

オンラインで試す


1

R194 172バイト

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)}

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

1(またはゼロ)に等しい行列の各セルから始まる深さ優先探索を実行します。

  • @Giuseppeのおかげで-2バイト
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.