เพื่อค้นหาหมู่เกาะที่ 1 และ 0 ในเมทริกซ์


29

กำหนดเมทริกซ์สองมิติเป็น 0 และ 1s ค้นหาจำนวนเกาะสำหรับ 1s และ 0s โดยที่เพื่อนบ้านอยู่ในแนวนอนและแนวตั้งเท่านั้น

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
คุณควรเพิ่ม testcase [[1,0];[0,1]]เพื่อให้แน่ใจว่าไม่มีการเชื่อมต่อในแนวทแยง
Sanchises

8
ฉันขอแนะนำให้ส่งออกสามารถในทั้งสองคำสั่งตราบเท่าที่มีการระบุคำสั่ง - มันไม่ได้เพิ่มมูลค่าใด ๆ ที่จะบังคับให้คำสั่ง
streetster

8
ยินดีต้อนรับสู่เว็บไซต์!
Arnauld

1
สิ่งที่ได้รับคำตอบในความคิดเห็นควรมีความชัดเจนในเนื้อหาของความท้าทาย และโดยเฉพาะอย่างยิ่งถ้าคุณต้องการให้เราคืนค่า 1 ก่อน 0 เป็นค่าที่ควรระบุไว้อย่างชัดเจน
Arnauld

4
กรณีทดสอบที่แนะนำ: 11111 / 10001 / 10101 / 10001 / 111112 1
Kevin Cruijssen

คำตอบ:


16

APL (Dyalog Unicode) , 29 28 ไบต์SBCS

-1 ต้องขอบคุณ @ Adám

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

ลองออนไลน์!

⊂,~∘⊂ เมทริกซ์และการปฏิเสธ

{ สำหรับแต่ละคนทำ

⍸⍵ รายการคู่ของคอร์ด 1s

+/↑|∘.-⍨ เมทริกซ์ของระยะทางแมนฮัตตัน

2> เมทริกซ์เพื่อนบ้าน

∨.∧⍨⍣≡ ปิดสกรรมกริยา

≢∪ จำนวนแถวที่ไม่ซ้ำกัน


นี่ฉลาดจริงๆ คุณช่วยอธิบายได้ไหมว่าเหตุใดบรรทัดสุดท้ายจึงรับประกันว่าจะทำงานเช่นทำไมแถวที่ไม่ซ้ำกันจึงเท่ากับคำตอบ นอกจากนี้ยังเป็น "ปิดสกรรมกริยา" เป็นเหมือนเจ^:_?
โยนาห์

1
@Jonah ดูแชท
ngn

16

J , 57 ไบต์

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

ลองออนไลน์!

นี่คือหนึ่งในสิ่งที่ความคิดนั้นเรียบง่ายอย่างเหลือเชื่อ (และฉันคิดว่าสนุก) แต่การดำเนินการมันมีความยาวเชิงกลซึ่งปกปิดความเรียบง่าย ... เช่นการเปลี่ยนเมทริกซ์ดั้งเดิมในทุกทิศทางด้วย 0 เติมคือ verbose ((,-)#:i.3) |.!.0verbose

อาจเป็นไปได้ที่ความยาวเชิงกลนี้จะสามารถเล่นกอล์ฟต่อไปได้และฉันอาจลองตอนเย็นวันพรุ่งนี้ แต่ฉันจะโพสต์ปมของมันตอนนี้

พูดว่าอินพุตของเราคือ:

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
ดูเหมือนว่าเป็นกลไก "เติมน้ำท่วม" เป็นระเบียบเรียบร้อยจริงๆ
Matthieu 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[0][1]2 's

เพื่อบันทึกไบต์ใช้รหัสเดียวกันที่แน่นอนสำหรับทั้งการทำซ้ำรูทและการทำซ้ำซ้ำ แต่มันทำงานแตกต่างกันเล็กน้อย

ในช่วงการทำซ้ำครั้งแรก:

  • V=0.5V-โวลต์0โวลต์=0โวลต์=1
  • XY(x-X)2+(Y-Y)2(x,Y)

ระหว่างการวนซ้ำแบบซ้ำ:

  • 2c[v ^ 1]++

ความคิดเห็น

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

รหัสนี้ใช้ไม่ได้กับเมทริกซ์ขนาดใหญ่เช่น 100 * 100 โดยมีเพียง 1 หรือ 0 วินาทีเนื่องจากสแตกล้น
KB joy

3
@KBjoy ยกเว้นกรณีที่ระบุไว้เป็นอย่างอื่นอย่างชัดเจนในความท้าทายกฎเริ่มต้นของเราคือเราไม่สนใจเกี่ยวกับข้อ จำกัด ในการใช้งานตราบใดที่อัลกอริทึมพื้นฐานทำงานในทฤษฎีสำหรับอินพุตใด ๆ ( นี่คือเมตาโพสต์เกี่ยวกับเรื่องนี้ แต่อาจมีความเกี่ยวข้องมากกว่าที่อื่น)
Arnauld

7

MATL , 14 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}'~:\

ลองออนไลน์!

~:\ คู่ของอินพุตและการปฏิเสธ (แท้จริง: negate iterate-converge)

{ }' แต่ละ

,/x เรียบ ARG

&1s อยู่ที่ไหน - รายการดัชนี

(0,#*x)\ ความกว้าง divmod (อินพุต) เพื่อรับสองรายการแยกกันสำหรับ ys และ xs

x-\:'x: ระยะต่อแกน ∆x และ ∆y

x*x: ยกกำลังสอง

+/ เพิ่ม ∆x² และ ∆y²

2> เมทริกซ์เพื่อนบ้าน

{|/'x*\:x}/ ปิดสกรรมกริยา

#? นับแถวที่ไม่ซ้ำกัน


หลังจากเห็นคำตอบของคุณฉันดีใจที่ฉันไม่ได้พยายามที่จะแก้ไขปัญหานี้ใน K :)
23929 ท้อง

2
@streetster ฮ่าฮ่าขอบคุณ! นั่นไม่ใช่เอฟเฟ็กต์ที่ฉันตั้งใจ :) จริง ๆ แล้วฉันอยากจะสนับสนุนให้ผู้คนเรียนรู้ (ภาษาถิ่นใด ๆ ) k และเล่นกอล์ฟในนั้น
ก.ย.

6

ภาษา Wolfram (Mathematica) , 64 62 ไบต์

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

ลองออนไลน์!

ขอบคุณattinat : เราสามารถเขียน1<0แทนFalseและบันทึกสองไบต์

รุ่นที่ไม่ตีกอล์ฟ:

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

แน่นอนว่ามีMathematica builtinMorphologicalComponentsที่ใช้อาเรย์ (หรือรูปภาพ) และส่งกลับค่าเดียวกันด้วยพิกเซลของแต่ละเกาะที่เชื่อมต่อทางสัณฐานวิทยาซึ่งถูกแทนที่ด้วยดัชนีเกาะ การบันทึกMaxผลลัพธ์นี้จะทำให้จำนวนเกาะ (ศูนย์หลังเหลือศูนย์และดัชนีเกาะเริ่มที่ 1) เราต้องทำสิ่งนี้แยกต่างหากสำหรับอาเรย์ (ให้หมายเลข 1 เกาะ) และอีกหนึ่งลบอาเรย์ (ให้จำนวน 0 เกาะ) เพื่อให้แน่ใจว่าเพื่อนบ้านเส้นทแยงมุมไม่นับเป็นเพื่อนบ้านตัวเลือกในการCornerNeighbors->Falseตอบสนองความต้องการที่จะได้รับ


-2 ไบต์เนื่องจากความไม่เท่าเทียมมีความสำคัญมากกว่าRule
attinat

5

Python 3 144 127 ไบต์

วิธีนี้ใช้cv2พลังการประมวลผลภาพที่ยอดเยี่ยม แม้จะมีชื่อวิธีการที่น่ากลัวน้อยกว่ายาวมากและอ่านง่าย แต่มันก็เต้นได้ทั้งคำตอบของ 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=4และn.uint8แทนที่จะเป็นdtype=n.uint8ไปได้หรือไม่
Kevin Cruijssen

@KevinCruijssen คุณต้องการชื่ออาร์กิวเมนต์ถ้าคุณข้ามอาร์กิวเมนต์ตัวเลือก เมื่อมองดูเอกสารฉันไม่จำเป็นต้องข้ามไปซึ่งช่วยฉันได้หลายไบต์ ขอบคุณ!
Daniel

อาตกลงฉันคิดว่ามันเป็นอย่างนั้น แต่เมื่อฉันดูเอกสารฉันสามารถหาcv2.connectedComponentsวิธีเดียวดังนั้นฉันสับสนและคิดว่าอาจมีเหตุผลที่แตกต่างกันสำหรับการต้องการชื่ออาร์กิวเมนต์ อย่างที่ฉันพูดฉันไม่คุ้นเคยกับ Python มากเกินไป ทั้งหมดที่ฉันได้เรียนรู้จากมันคือจากที่นี่ใน CCGC ;) แต่มันสมเหตุสมผลที่จะใช้ชื่อตัวแปรเพื่อข้ามอาร์กิวเมนต์ตัวเลือกอื่น ๆ
Kevin Cruijssen

1
ดีมาก! ผมพบว่าคอมไพเลอร์ออนไลน์ซึ่งรวมถึงโมดูล CV2 ที่นี่
Jitse

5

J , 46 44 43 ไบต์

-1 ไบต์ขอบคุณ @miles

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

ลองออนไลน์!

การทดสอบและ,& -.เสื้อคลุมที่ขโมยมาจากคำตอบของ @ jonah

,& -. สำหรับอินพุตและการปฏิเสธทำ:

4$.$. (y, x) พิกัดของ 1s เป็นเมทริกซ์ n × 2

1#.[:|@-"1/~ แมนฮัตตันระยะทาง: abs (∆x) + abs (∆y)

2> เมทริกซ์เพื่อนบ้าน

[:+./ .*~^:_: ปิดสกรรมกริยา

#&~.&( ) จำนวนแถวที่ไม่ซ้ำกัน


1
คุณสามารถเขียนความยาวและความเป็นเอกลักษณ์เพื่อบันทึกไบต์อื่น ๆ เช่น,&#&~.หลีกเลี่ยงการใช้[:
ไมล์

@miles ขอบคุณ
NGN

3

เรติน่า 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 ที่อยู่ติดกันด้วย;s

}

ทำซ้ำจนกว่าทั้งหมดของหมู่เกาะใน1s ได้รับกลายเป็น;s

s`0(.*)
:$1b

หากมีให้0เปลี่ยนเป็น:และผนวก a bถึงจุดสิ้นสุดของอินพุตเพื่อให้ไม่สามารถแก้ไขได้

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

น้ำท่วมเติม0s ที่อยู่ติดกันด้วย:s

}

ทำซ้ำจนกว่าทั้งหมดของหมู่เกาะใน0s ได้รับกลายเป็น:s

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

แยกนับตัวเลขของเกาะ1และ0s


3

Haskell , 228 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..]

ลองออนไลน์!

คำอธิบาย:

ความคิดสำหรับการแก้ปัญหานี้จะเป็นดังนี้: initialise เมทริกซ์ที่มีค่าที่ไม่ซ้ำกันในแต่ละเซลล์ในเชิงบวกสำหรับและเชิงลบสำหรับ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การโกนไม่กี่ไบต์ สิ่งที่เราทำที่นี่คือซิปอาเรย์สองมิติพร้อมดัชนีจำนวนเต็มที่แถวและดัชนีเลขจำนวนเต็มคี่ที่คอลัมน์ เราทำเช่นนี้เนื่องจากเราสามารถสร้างจำนวนเต็มไม่ซ้ำกันจากคู่ของจำนวนเต็มโดยใช้สูตรที่(i,j) (2^i)*(2j+1)หากเราสร้างจำนวนเต็มคี่สำหรับjเราสามารถข้ามการคำนวณ2*j+1และบันทึกสามไบต์

ด้วยหมายเลขที่ไม่ซ้ำกันตอนนี้เราต้องคูณด้วยเครื่องหมายตามค่าในเมทริกซ์ซึ่งได้มาเป็น 2*x-1

การย้ำ

การวนซ้ำทำได้โดย

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

เนื่องจากอินพุตอยู่ในรูปแบบของรายการเราจึงทำการเปรียบเทียบเพื่อนบ้านในแต่ละแถวย้ายเมทริกซ์ทำการเปรียบเทียบในแต่ละแถวอีกครั้ง (ซึ่งเนื่องจากการแปลงเป็นคอลัมน์ก่อนหน้านี้) และเปลี่ยนอีกครั้ง รหัสที่สำเร็จหนึ่งในขั้นตอนเหล่านี้คือ

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

โดยที่lฟังก์ชั่นการเปรียบเทียบ (รายละเอียดด้านล่าง) และtranspose.map lดำเนินการครึ่งหนึ่งของขั้นตอนการเปรียบเทียบและการขนย้าย (.)>>=idดำเนินการโต้แย้งสองครั้งเป็นรูปแบบ pointfree \f -> f.fและสั้นลงหนึ่งไบต์ในกรณีนี้เนื่องจากกฎที่มีความสำคัญกว่าผู้ประกอบการ

ll x=z(!)(z(!)x(0:x))$tail x++[0]ถูกกำหนดไว้ในแถวด้านบนเป็น รหัสนี้ดำเนินการตัวดำเนินการเปรียบเทียบ(!)(ดูด้านล่าง) ในทุกเซลล์ที่มีเพื่อนบ้านด้านซ้ายก่อนแล้วจึงมีเพื่อนบ้านที่เหมาะสมโดยการซิปรายการที่xมีรายการที่เลื่อนด้านขวา0:xและรายการที่เลื่อนด้านซ้ายtail x++[0]ในทางกลับกัน เราใช้ศูนย์เพื่อรองรายการที่ถูกเลื่อนเนื่องจากมันไม่สามารถเกิดขึ้นได้ในเมทริกซ์ที่ประมวลผลล่วงหน้า

a!ba!b=div(max(a*a)(a*b))aถูกกำหนดไว้ในแถวข้างต้นนี้เป็น สิ่งที่เราต้องการทำที่นี่คือความแตกต่างกรณีดังต่อไปนี้:

  • หากsgn(a) = -sgn(b)เรามีพื้นที่ตรงข้ามสองแห่งในเมทริกซ์และไม่ต้องการรวมมันเข้าด้วยกันดังนั้นaไม่เปลี่ยนแปลง
  • หากsgn(b) = 0เรามีกรณีมุมซึ่งbเป็นช่องว่างภายในและดังนั้นจึงaยังคงไม่เปลี่ยนแปลง
  • หากsgn(a) = sgn(b)เราต้องการรวมสองพื้นที่และนำสิ่งที่มีค่าสัมบูรณ์ที่ใหญ่กว่า (เพื่อประโยชน์ของความสะดวกสบาย)

โปรดทราบว่าไม่สามารถจะsgn(a) 0เราทำสิ่งนี้สำเร็จด้วยสูตรที่กำหนด หากมีอาการของaและbแตกต่างกัน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=<<((==)=<<))ซึ่งนำมาจากคำตอบสแต็คโอเวอร์โฟลว์นี้นี้

postprocessing

สำหรับการประมวลผลภายหลังเราใช้ชิ้นส่วน

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

-74 ไบต์ขอบคุณ@NahuelFouilleul @NahuelFouilleul

ลองออนไลน์

คำอธิบาย:

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! และฉันยังสามารถใช้<2แทน==1-1 byte โดยการตรวจสอบก่อน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
ฉันกลัว OP [#1, #0]ที่กล่าวถึงในความคิดเห็นที่สองเพื่อที่ควรจะเป็น Bit imo ที่ไม่มีจุดหมายเพื่อบังคับใช้สิ่งนี้ แต่ตอนนี้มันเป็นสิ่งที่จำเป็น อย่างไรก็ตามคุณสามารถตีกอล์ฟ{not c}ไปที่{c^1}และแก้ไขปัญหาที่ฉันกล่าวถึงโดยการเปลี่ยนn[c]+=ไปใช้n[c^1]+=ในเรื่องที่คล้ายกัน คำตอบที่ดี +1 จากฉัน :)
Kevin Cruijssen

อ่าคุณพูดถูก ขอบคุณ!
Jitse

1

Perl 5 ( -0777p), 110 ไบต์

อาจจะดีขึ้น, ใช้ regex เพื่อแทนที่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€Ẉ

ลองออนไลน์!

ลิงก์ monadic ยอมรับรายการของจำนวนเต็มเป็นอาร์กิวเมนต์และส่งคืนรายการจำนวน 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

R , 194 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 (หรือศูนย์)

  • -2 ไบต์ขอบคุณ @Giuseppe
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.