From 65719fdc113c4f7b222b7835dda8e431af467f6a Mon Sep 17 00:00:00 2001 From: Edgar Date: Wed, 25 Oct 2023 14:19:34 -0700 Subject: [PATCH 1/4] Add new algorithm index_2d_array_in_1d --- .../arrays/index_2d_array_in_1d.py | 107 ++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 data_structures/arrays/index_2d_array_in_1d.py diff --git a/data_structures/arrays/index_2d_array_in_1d.py b/data_structures/arrays/index_2d_array_in_1d.py new file mode 100644 index 000000000000..f77d29e3085d --- /dev/null +++ b/data_structures/arrays/index_2d_array_in_1d.py @@ -0,0 +1,107 @@ +""" +Retrieves the value of an 0-indexed 1D index from a 2D array. +There are two ways to retrieve value(s): + +1. index_2d_array_in_1d(array: list[int], index: int) -> int +This function allows you to provide a 2D array and a 0-indexed 1D integer index, +and retrieves the integer value at that index. + +2. Index2DArrayIterator(array) -> Iterator[int] +This iterator allows you to iterate through a 2D array by passing in the array and +calling __next__() on your iterator. You can also use the iterator in a loop. +Example: +[value for value in Index2DArrayIterator(array)] + +Python doctests can be run using this command: +python3 -m doctest -v index_2d_array_in_1d.py +""" + +from collections.abc import Iterator + + +class Index2DArrayIterator: + """ + Creates an iterator to iterate through the values in the given 2D array. + + Args: + array (List[int]): A 2D array of integers where all rows are the same size + and all columns are the same size. + """ + + def __init__(self, array: list[list[int]]): + self.array = array + self.cols = len(array[0]) + self.n = len(array) * len(array[0]) + self.i = 0 + + def __iter__(self) -> Iterator[int]: + return self + + def __next__(self) -> int: + """ + Returns the next item in the array. + + Returns: + int: Value in array. + + >>> t = Index2DArrayIterator([[5],[-523],[-1],[34],[0]]) + >>> t.__next__() + 5 + >>> t.__next__() + -523 + >>> u = Index2DArrayIterator([[5, 2, 25], [23, 14, 5], [324, -1, 0]]) + >>> [val for val in u] + [5, 2, 25, 23, 14, 5, 324, -1, 0] + """ + if self.i < self.n: + x = self.array[self.i // self.cols][self.i % self.cols] + self.i += 1 + return x + else: + raise StopIteration + + +def index_2d_array_in_1d(array: list[list[int]], index: int) -> int: + """ + Retrieves the value of the one-dimensional index from a two-dimensional array. + + Args: + array (List[int]): A 2D array of integers where all rows are the same size and + all columns are the same size. + index: A 1D index. + + Returns: + int: The 0-indexed value of the 1D index in the array. + + Examples: + >>> index_2d_array_in_1d([[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]], 5) + 5 + >>> index_2d_array_in_1d([[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]], -1) + Traceback (most recent call last): + ... + ValueError: index out of range + >>> index_2d_array_in_1d([[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]], 12) + Traceback (most recent call last): + ... + ValueError: index out of range + >>> index_2d_array_in_1d([[]], 0) + Traceback (most recent call last): + ... + ValueError: no items in array + """ + rows = len(array) + cols = len(array[0]) + + if rows == 0 or cols == 0: + raise ValueError("no items in array") + + if index < 0 or index >= rows * cols: + raise ValueError("index out of range") + + return array[index // cols][index % cols] + + +if __name__ == "__main__": + import doctest + + doctest.testmod() From 36ae5431697083d9671b4903bf3f37135f64191a Mon Sep 17 00:00:00 2001 From: Edgar Date: Wed, 25 Oct 2023 14:28:53 -0700 Subject: [PATCH 2/4] Add doctest for iter function --- data_structures/arrays/index_2d_array_in_1d.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/data_structures/arrays/index_2d_array_in_1d.py b/data_structures/arrays/index_2d_array_in_1d.py index f77d29e3085d..8a9adc2bb7cc 100644 --- a/data_structures/arrays/index_2d_array_in_1d.py +++ b/data_structures/arrays/index_2d_array_in_1d.py @@ -28,13 +28,18 @@ class Index2DArrayIterator: and all columns are the same size. """ - def __init__(self, array: list[list[int]]): + def __init__(self, array: list[list[int]]) -> None: self.array = array self.cols = len(array[0]) self.n = len(array) * len(array[0]) self.i = 0 def __iter__(self) -> Iterator[int]: + """ + >>> t = Index2DArrayIterator([[5],[-523],[-1],[34],[0]]) + >>> t.__iter__() is not None + True + """ return self def __next__(self) -> int: From b9e33dc2263339c89f81200a1f461ceaaecb62f0 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Thu, 26 Oct 2023 16:26:30 +0200 Subject: [PATCH 3/4] The power of dataclasses --- .../arrays/index_2d_array_in_1d.py | 103 ++++++++---------- 1 file changed, 48 insertions(+), 55 deletions(-) diff --git a/data_structures/arrays/index_2d_array_in_1d.py b/data_structures/arrays/index_2d_array_in_1d.py index 8a9adc2bb7cc..6106be318da8 100644 --- a/data_structures/arrays/index_2d_array_in_1d.py +++ b/data_structures/arrays/index_2d_array_in_1d.py @@ -2,68 +2,61 @@ Retrieves the value of an 0-indexed 1D index from a 2D array. There are two ways to retrieve value(s): -1. index_2d_array_in_1d(array: list[int], index: int) -> int +1. Index2DArrayIterator(array) -> Iterator[int] +This iterator allows you to iterate through a 2D array by passing in the array and +calling next(your_iterator). You can also use the iterator in a loop. +Examples: +list(Index2DArrayIterator(array)) +set(Index2DArrayIterator(array)) +tuple(Index2DArrayIterator(array)) +sum(Index2DArrayIterator(array)) +-5 in Index2DArrayIterator(array) + +2. index_2d_array_in_1d(array: list[int], index: int) -> int This function allows you to provide a 2D array and a 0-indexed 1D integer index, and retrieves the integer value at that index. -2. Index2DArrayIterator(array) -> Iterator[int] -This iterator allows you to iterate through a 2D array by passing in the array and -calling __next__() on your iterator. You can also use the iterator in a loop. -Example: -[value for value in Index2DArrayIterator(array)] - Python doctests can be run using this command: python3 -m doctest -v index_2d_array_in_1d.py """ from collections.abc import Iterator +from dataclasses import dataclass +@dataclass class Index2DArrayIterator: - """ - Creates an iterator to iterate through the values in the given 2D array. - - Args: - array (List[int]): A 2D array of integers where all rows are the same size - and all columns are the same size. - """ - - def __init__(self, array: list[list[int]]) -> None: - self.array = array - self.cols = len(array[0]) - self.n = len(array) * len(array[0]) - self.i = 0 + matrix: list[list[int]] def __iter__(self) -> Iterator[int]: """ - >>> t = Index2DArrayIterator([[5],[-523],[-1],[34],[0]]) - >>> t.__iter__() is not None + >>> tuple(Index2DArrayIterator([[5], [-523], [-1], [34], [0]])) + (5, -523, -1, 34, 0) + >>> tuple(Index2DArrayIterator([[5, -523, -1], [34, 0]])) + (5, -523, -1, 34, 0) + >>> tuple(Index2DArrayIterator([[5, -523, -1, 34, 0]])) + (5, -523, -1, 34, 0) + >>> t = Index2DArrayIterator([[5, 2, 25], [23, 14, 5], [324, -1, 0]]) + >>> tuple(t) + (5, 2, 25, 23, 14, 5, 324, -1, 0) + >>> list(t) + [5, 2, 25, 23, 14, 5, 324, -1, 0] + >>> sorted(t) + [-1, 0, 2, 5, 5, 14, 23, 25, 324] + >>> tuple(t)[3] + 23 + >>> sum(t) + 397 + >>> -1 in t True - """ - return self - - def __next__(self) -> int: - """ - Returns the next item in the array. - - Returns: - int: Value in array. - - >>> t = Index2DArrayIterator([[5],[-523],[-1],[34],[0]]) - >>> t.__next__() + >>> t = iter(Index2DArrayIterator([[5], [-523], [-1], [34], [0]])) + >>> next(t) 5 - >>> t.__next__() + >>> next(t) -523 - >>> u = Index2DArrayIterator([[5, 2, 25], [23, 14, 5], [324, -1, 0]]) - >>> [val for val in u] - [5, 2, 25, 23, 14, 5, 324, -1, 0] """ - if self.i < self.n: - x = self.array[self.i // self.cols][self.i % self.cols] - self.i += 1 - return x - else: - raise StopIteration + for row in self.matrix: + yield from row def index_2d_array_in_1d(array: list[list[int]], index: int) -> int: @@ -79,20 +72,20 @@ def index_2d_array_in_1d(array: list[list[int]], index: int) -> int: int: The 0-indexed value of the 1D index in the array. Examples: - >>> index_2d_array_in_1d([[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]], 5) - 5 - >>> index_2d_array_in_1d([[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]], -1) - Traceback (most recent call last): + >>> index_2d_array_in_1d([[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]], 5) + 5 + >>> index_2d_array_in_1d([[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]], -1) + Traceback (most recent call last): ... - ValueError: index out of range - >>> index_2d_array_in_1d([[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]], 12) - Traceback (most recent call last): + ValueError: index out of range + >>> index_2d_array_in_1d([[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]], 12) + Traceback (most recent call last): ... - ValueError: index out of range - >>> index_2d_array_in_1d([[]], 0) - Traceback (most recent call last): + ValueError: index out of range + >>> index_2d_array_in_1d([[]], 0) + Traceback (most recent call last): ... - ValueError: no items in array + ValueError: no items in array """ rows = len(array) cols = len(array[0]) From d9e6445e166f02a1439c428b89873b3f94433756 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Thu, 26 Oct 2023 16:30:19 +0200 Subject: [PATCH 4/4] Update index_2d_array_in_1d.py --- data_structures/arrays/index_2d_array_in_1d.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/data_structures/arrays/index_2d_array_in_1d.py b/data_structures/arrays/index_2d_array_in_1d.py index 6106be318da8..27a9fa5f9121 100644 --- a/data_structures/arrays/index_2d_array_in_1d.py +++ b/data_structures/arrays/index_2d_array_in_1d.py @@ -2,15 +2,15 @@ Retrieves the value of an 0-indexed 1D index from a 2D array. There are two ways to retrieve value(s): -1. Index2DArrayIterator(array) -> Iterator[int] -This iterator allows you to iterate through a 2D array by passing in the array and +1. Index2DArrayIterator(matrix) -> Iterator[int] +This iterator allows you to iterate through a 2D array by passing in the matrix and calling next(your_iterator). You can also use the iterator in a loop. Examples: -list(Index2DArrayIterator(array)) -set(Index2DArrayIterator(array)) -tuple(Index2DArrayIterator(array)) -sum(Index2DArrayIterator(array)) --5 in Index2DArrayIterator(array) +list(Index2DArrayIterator(matrix)) +set(Index2DArrayIterator(matrix)) +tuple(Index2DArrayIterator(matrix)) +sum(Index2DArrayIterator(matrix)) +-5 in Index2DArrayIterator(matrix) 2. index_2d_array_in_1d(array: list[int], index: int) -> int This function allows you to provide a 2D array and a 0-indexed 1D integer index, @@ -64,8 +64,8 @@ def index_2d_array_in_1d(array: list[list[int]], index: int) -> int: Retrieves the value of the one-dimensional index from a two-dimensional array. Args: - array (List[int]): A 2D array of integers where all rows are the same size and - all columns are the same size. + array: A 2D array of integers where all rows are the same size and all + columns are the same size. index: A 1D index. Returns: