mirror of
https://github.com/TheAlgorithms/Python.git
synced 2026-09-28 21:45:27 +08:00
Added doctests for matrix/count_islands_in_matrix.py (#12555)
* Added doctests for matrix/count_islands_in_matrix.py * Changed matrix initialisation in count_islands_in_matrix.py. Addressing requested changes on #12555 * Fixed accidental code change * Deleted unnecessary comment. Addressing to requested changes on #12555 * Removing another unnecessary comment. Addressing a requested change on #12555 * Fix return statement in count_islands function Ensure the function returns the island count correctly. * Update doctest comments for whitespace normalization --------- Co-authored-by: CheerfulBear22 <> Co-authored-by: Christian Clauss <cclauss@me.com>
This commit is contained in:
co-authored by
CheerfulBear22 <>
Christian Clauss
parent
52b9b913e0
commit
784c3eaf58
@@ -2,58 +2,41 @@
|
||||
# This code counts number of islands in a given matrix, with including diagonal
|
||||
# connections.
|
||||
class Matrix: # Public class to implement a graph
|
||||
"""This public class represents the 2-Dimensional matrix to count
|
||||
the number of islands.An island is the connected group of 1s,including the top,
|
||||
down, right, left as well as the diagonal connections.
|
||||
>>> matrix1 = Matrix(3, 3, [[1, 1, 0], [0, 1, 0], [1, 0, 1]])
|
||||
>>> matrix1.count_islands()
|
||||
1
|
||||
>>> matrix2 = Matrix(2, 2, [[1, 1], [1, 1]])
|
||||
>>> matrix2.count_islands()
|
||||
1
|
||||
"""
|
||||
|
||||
def __init__(self, row: int, col: int, graph: list[list[bool]]) -> None:
|
||||
"""Initializes the matrix with the given number of rows, columns and matrix.
|
||||
Args:
|
||||
row (int): number of rows in the matrix
|
||||
col (int): number of columns in the matrix
|
||||
graph (list[list[bool]]): 2-D list of 0s and 1s representing the matrix
|
||||
def __init__(self, graph: list[list[bool]]) -> None:
|
||||
"""
|
||||
Initialise matrix with number of rows, columns, and graph.
|
||||
|
||||
>>> m = Matrix([[True, False, False, False],
|
||||
... [True, False, True, False],
|
||||
... [False, False, True, True]])
|
||||
>>> m.ROW
|
||||
3
|
||||
>>> m.COL
|
||||
4
|
||||
>>> m.graph # doctest: +NORMALIZE_WHITESPACE
|
||||
[[True, False, False, False],
|
||||
[True, False, True, False],
|
||||
[False, False, True, True]]
|
||||
"""
|
||||
self.ROW = row
|
||||
self.COL = col
|
||||
self.graph = graph
|
||||
self.ROW = len(graph)
|
||||
self.COL = len(graph[0])
|
||||
|
||||
def is_safe(self, i: int, j: int, visited: list[list[bool]]) -> bool:
|
||||
"""This checks if the current cell can be included in the current island.
|
||||
Args:
|
||||
i (int): row index
|
||||
j (int): column index
|
||||
visited (list[list[bool]]): 2D list tracking the visited cells
|
||||
Returns:
|
||||
bool: True if the cell is in bounds, not yet visited and part of
|
||||
an island (its value is ``1``); False otherwise.
|
||||
>>> visited = [[False, False], [False, False]]
|
||||
>>> graph = [[1, 0], [0, 1]]
|
||||
>>> m = Matrix(2, 2, graph)
|
||||
"""
|
||||
>>> visited = [[False, False, False],
|
||||
... [False, False, False],
|
||||
... [False, False, False]]
|
||||
>>> m = Matrix([[True, False, False],
|
||||
... [False, False, True],
|
||||
... [False, False, True]])
|
||||
>>> m.is_safe(0, 0, visited)
|
||||
True
|
||||
>>> m.is_safe(0, 1, visited)
|
||||
False
|
||||
|
||||
A cell that is out of bounds is never safe:
|
||||
|
||||
>>> m.is_safe(-1, 0, visited)
|
||||
False
|
||||
>>> m.is_safe(0, 2, visited)
|
||||
False
|
||||
|
||||
Only cells whose value is exactly ``1`` are part of an island, so any
|
||||
other value (e.g. ``2``) is treated as water, matching the seeding rule
|
||||
used by ``count_islands``:
|
||||
|
||||
>>> m2 = Matrix(1, 1, [[2]])
|
||||
>>> m2.is_safe(0, 0, [[False]])
|
||||
>>> m.is_safe(-1, 2, visited)
|
||||
False
|
||||
>>> m.is_safe(1, 5, visited)
|
||||
False
|
||||
"""
|
||||
return (
|
||||
@@ -64,20 +47,21 @@ class Matrix: # Public class to implement a graph
|
||||
)
|
||||
|
||||
def diffs(self, i: int, j: int, visited: list[list[bool]]) -> None:
|
||||
"""This is the recursive function to mark all the cells visited which
|
||||
are connected to (i, j) indices.
|
||||
Args:
|
||||
i (int): row index
|
||||
j (int): column index
|
||||
visited (list[list[bool]]): 2D list tracking the visited cells
|
||||
>>> visited = [[False, False], [False, False]]
|
||||
>>> graph = [[1, 1], [0, 1]]
|
||||
>>> m = Matrix(2, 2, graph)
|
||||
>>> m.diffs(0, 0, visited)
|
||||
>>> visited
|
||||
[[True, True], [False, True]]
|
||||
"""
|
||||
# Checking all 8 elements surrounding nth element
|
||||
Checking all 8 elements surrounding nth element.
|
||||
|
||||
>>> visited = [[False, False, False],
|
||||
... [False, False, False],
|
||||
... [False, False, False]]
|
||||
>>> m = Matrix([[True, True, False],
|
||||
... [False, True, False],
|
||||
... [True, False, True]])
|
||||
>>> m.diffs(0, 0, visited)
|
||||
>>> visited # doctest: +NORMALIZE_WHITESPACE
|
||||
[[True, True, False],
|
||||
[False, True, False],
|
||||
[True, False, True]]
|
||||
"""
|
||||
row_nbr = [-1, -1, -1, 0, 0, 1, 1, 1] # Coordinate order
|
||||
col_nbr = [-1, 0, 1, -1, 1, -1, 0, 1]
|
||||
visited[i][j] = True # Make those cells visited
|
||||
@@ -85,50 +69,24 @@ class Matrix: # Public class to implement a graph
|
||||
if self.is_safe(i + row_nbr[k], j + col_nbr[k], visited):
|
||||
self.diffs(i + row_nbr[k], j + col_nbr[k], visited)
|
||||
|
||||
def count_islands(self) -> int: # And finally, count all islands.
|
||||
def count_islands(self) -> int:
|
||||
"""
|
||||
This counts all the islands in the given matrix.
|
||||
Returns:
|
||||
int: the number of islands in the given matrix.
|
||||
Example -
|
||||
>>> mat = Matrix(1, 1, [[1]])
|
||||
>>> mat.count_islands()
|
||||
1
|
||||
>>> mat2 = Matrix(2, 2, [[0, 0], [0, 0]])
|
||||
>>> mat2.count_islands()
|
||||
0
|
||||
|
||||
Two 1s that only touch on a diagonal still form a single island:
|
||||
|
||||
>>> Matrix(2, 2, [[1, 0], [0, 1]]).count_islands()
|
||||
1
|
||||
|
||||
Two islands separated by a column of water:
|
||||
|
||||
>>> Matrix(3, 3, [[1, 0, 1], [1, 0, 1], [0, 0, 1]]).count_islands()
|
||||
>>> m = Matrix([[True, True, False, False],
|
||||
... [False, True, False, True],
|
||||
... [True, False, False, True]])
|
||||
>>> m.count_islands()
|
||||
2
|
||||
|
||||
``count_islands`` seeds a new island only on cells equal to ``1``.
|
||||
Before ``is_safe`` was aligned to the same rule it expanded into any
|
||||
truthy cell, so a matrix containing values other than ``0``/``1``
|
||||
reported the wrong count. Here two ``1``s are bridged by a ``2``:
|
||||
because a ``2`` is not part of an island they must be counted as two
|
||||
separate islands. The old truthy check absorbed the ``2`` and
|
||||
merged them into one, returning ``1`` instead of ``2``:
|
||||
|
||||
>>> Matrix(1, 3, [[1, 2, 1]]).count_islands()
|
||||
>>> m2 = Matrix([[True, True, False],
|
||||
... [True, False, False],
|
||||
... [False, False, True]])
|
||||
>>> m2.count_islands()
|
||||
2
|
||||
|
||||
A lone ``2`` is likewise not an island:
|
||||
|
||||
>>> Matrix(1, 1, [[2]]).count_islands()
|
||||
0
|
||||
"""
|
||||
visited = [[False for j in range(self.COL)] for i in range(self.ROW)]
|
||||
count = 0
|
||||
for i in range(self.ROW):
|
||||
for j in range(self.COL):
|
||||
if visited[i][j] is False and self.graph[i][j] == 1:
|
||||
if not visited[i][j] and self.graph[i][j]:
|
||||
self.diffs(i, j, visited)
|
||||
count += 1
|
||||
return count
|
||||
|
||||
Reference in New Issue
Block a user