22# This code counts number of islands in a given matrix, with including diagonal
33# connections.
44class Matrix : # Public class to implement a graph
5- """This public class represents the 2-Dimensional matrix to count
6- the number of islands.An island is the connected group of 1s,including the top,
7- down, right, left as well as the diagonal connections.
8- >>> matrix1 = Matrix(3, 3, [[1, 1, 0], [0, 1, 0], [1, 0, 1]])
9- >>> matrix1.count_islands()
10- 1
11- >>> matrix2 = Matrix(2, 2, [[1, 1], [1, 1]])
12- >>> matrix2.count_islands()
13- 1
14- """
15-
16- def __init__ (self , row : int , col : int , graph : list [list [bool ]]) -> None :
17- """Initializes the matrix with the given number of rows, columns and matrix.
18- Args:
19- row (int): number of rows in the matrix
20- col (int): number of columns in the matrix
21- graph (list[list[bool]]): 2-D list of 0s and 1s representing the matrix
5+ def __init__ (self , graph : list [list [bool ]]) -> None :
6+ """
7+ Initialise matrix with number of rows, columns, and graph.
8+
9+ >>> m = Matrix([[True, False, False, False],
10+ ... [True, False, True, False],
11+ ... [False, False, True, True]])
12+ >>> m.ROW
13+ 3
14+ >>> m.COL
15+ 4
16+ >>> m.graph # doctest: +NORMALIZE_WHITESPACE
17+ [[True, False, False, False],
18+ [True, False, True, False],
19+ [False, False, True, True]]
2220 """
23- self .ROW = row
24- self .COL = col
2521 self .graph = graph
22+ self .ROW = len (graph )
23+ self .COL = len (graph [0 ])
2624
2725 def is_safe (self , i : int , j : int , visited : list [list [bool ]]) -> bool :
28- """This checks if the current cell can be included in the current island.
29- Args:
30- i (int): row index
31- j (int): column index
32- visited (list[list[bool]]): 2D list tracking the visited cells
33- Returns:
34- bool: True if the cell is in bounds, not yet visited and part of
35- an island (its value is ``1``); False otherwise.
36- >>> visited = [[False, False], [False, False]]
37- >>> graph = [[1, 0], [0, 1]]
38- >>> m = Matrix(2, 2, graph)
26+ """
27+ >>> visited = [[False, False, False],
28+ ... [False, False, False],
29+ ... [False, False, False]]
30+ >>> m = Matrix([[True, False, False],
31+ ... [False, False, True],
32+ ... [False, False, True]])
3933 >>> m.is_safe(0, 0, visited)
4034 True
41- >>> m.is_safe(0, 1, visited)
42- False
43-
44- A cell that is out of bounds is never safe:
45-
46- >>> m.is_safe(-1, 0, visited)
47- False
4835 >>> m.is_safe(0, 2, visited)
4936 False
50-
51- Only cells whose value is exactly ``1`` are part of an island, so any
52- other value (e.g. ``2``) is treated as water, matching the seeding rule
53- used by ``count_islands``:
54-
55- >>> m2 = Matrix(1, 1, [[2]])
56- >>> m2.is_safe(0, 0, [[False]])
37+ >>> m.is_safe(-1, 2, visited)
38+ False
39+ >>> m.is_safe(1, 5, visited)
5740 False
5841 """
5942 return (
@@ -64,71 +47,46 @@ def is_safe(self, i: int, j: int, visited: list[list[bool]]) -> bool:
6447 )
6548
6649 def diffs (self , i : int , j : int , visited : list [list [bool ]]) -> None :
67- """This is the recursive function to mark all the cells visited which
68- are connected to (i, j) indices .
69- Args:
70- i (int): row index
71- j (int): column index
72- visited (list[list[bool]]): 2D list tracking the visited cells
73- >>> visited = [[False, False], [ False, False]]
74- >>> graph = [[1, 1], [0, 1]]
75- >>> m = Matrix(2, 2, graph )
50+ """
51+ Checking all 8 elements surrounding nth element .
52+
53+ >>> visited = [[False, False, False],
54+ ... [False, False, False],
55+ ... [False, False, False]]
56+ >>> m = Matrix([[True, True, False],
57+ ... [False, True, False],
58+ ... [True, False, True]] )
7659 >>> m.diffs(0, 0, visited)
77- >>> visited
78- [[True, True], [False, True]]
60+ >>> visited # doctest: +NORMALIZE_WHITESPACE
61+ [[True, True, False],
62+ [False, True, False],
63+ [True, False, True]]
7964 """
80- # Checking all 8 elements surrounding nth element
8165 row_nbr = [- 1 , - 1 , - 1 , 0 , 0 , 1 , 1 , 1 ] # Coordinate order
8266 col_nbr = [- 1 , 0 , 1 , - 1 , 1 , - 1 , 0 , 1 ]
8367 visited [i ][j ] = True # Make those cells visited
8468 for k in range (8 ):
8569 if self .is_safe (i + row_nbr [k ], j + col_nbr [k ], visited ):
8670 self .diffs (i + row_nbr [k ], j + col_nbr [k ], visited )
8771
88- def count_islands (self ) -> int : # And finally, count all islands.
72+ def count_islands (self ) -> int :
8973 """
90- This counts all the islands in the given matrix.
91- Returns:
92- int: the number of islands in the given matrix.
93- Example -
94- >>> mat = Matrix(1, 1, [[1]])
95- >>> mat.count_islands()
96- 1
97- >>> mat2 = Matrix(2, 2, [[0, 0], [0, 0]])
98- >>> mat2.count_islands()
99- 0
100-
101- Two 1s that only touch on a diagonal still form a single island:
102-
103- >>> Matrix(2, 2, [[1, 0], [0, 1]]).count_islands()
104- 1
105-
106- Two islands separated by a column of water:
107-
108- >>> Matrix(3, 3, [[1, 0, 1], [1, 0, 1], [0, 0, 1]]).count_islands()
74+ >>> m = Matrix([[True, True, False, False],
75+ ... [False, True, False, True],
76+ ... [True, False, False, True]])
77+ >>> m.count_islands()
10978 2
110-
111- ``count_islands`` seeds a new island only on cells equal to ``1``.
112- Before ``is_safe`` was aligned to the same rule it expanded into any
113- truthy cell, so a matrix containing values other than ``0``/``1``
114- reported the wrong count. Here two ``1``s are bridged by a ``2``:
115- because a ``2`` is not part of an island they must be counted as two
116- separate islands. The old truthy check absorbed the ``2`` and
117- merged them into one, returning ``1`` instead of ``2``:
118-
119- >>> Matrix(1, 3, [[1, 2, 1]]).count_islands()
79+ >>> m2 = Matrix([[True, True, False],
80+ ... [True, False, False],
81+ ... [False, False, True]])
82+ >>> m2.count_islands()
12083 2
121-
122- A lone ``2`` is likewise not an island:
123-
124- >>> Matrix(1, 1, [[2]]).count_islands()
125- 0
12684 """
12785 visited = [[False for j in range (self .COL )] for i in range (self .ROW )]
12886 count = 0
12987 for i in range (self .ROW ):
13088 for j in range (self .COL ):
131- if visited [i ][j ] is False and self .graph [i ][j ] == 1 :
89+ if not visited [i ][j ] and self .graph [i ][j ]:
13290 self .diffs (i , j , visited )
13391 count += 1
13492 return count
0 commit comments