Skip to content

Commit

Permalink
restrict Matrix to contain integer entries only, refactor monge_leftm…
Browse files Browse the repository at this point in the history
…ost_minimums
  • Loading branch information
wojtask committed Oct 6, 2024
1 parent c057e8f commit b0e37f6
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 23 deletions.
14 changes: 6 additions & 8 deletions src/book/data_structures.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,10 @@ class Matrix:
__end_row: int
__start_col: int
__end_col: int
__elements: list[list[int | float]]
__elements: list[list[int]]

def __init__(self, end_row: int, end_col: int, start_row: int = 1, start_col: int = 1,
elements: list[list[int | float]] | None = None) -> None:
elements: list[list[int]] | None = None) -> None:
if elements is None:
assert start_row == 1
assert start_col == 1
Expand All @@ -96,16 +96,14 @@ def even_rows_submatrix(self) -> "Matrix":
return Matrix(start_row=self.__start_row, end_row=submatrix_end_row, start_col=self.__start_col,
end_col=self.__end_col, elements=even_rows)

def __getitem__(self, indices: tuple[int, int]) -> int | float:
row = indices[0]
col = indices[1]
def __getitem__(self, indices: tuple[int, int]) -> int:
row, col = indices[0], indices[1]
assert 1 <= row <= self.__end_row - self.__start_row + 1
assert 1 <= col <= self.__end_col - self.__start_col + 1
return self.__elements[self.__start_row - 1 + row - 1][self.__start_col - 1 + col - 1]

def __setitem__(self, indices: tuple[int, int], value: int | float) -> None:
row = indices[0]
col = indices[1]
def __setitem__(self, indices: tuple[int, int], value: int) -> None:
row, col = indices[0], indices[1]
assert 1 <= row <= self.__end_row - self.__start_row + 1
assert 1 <= col <= self.__end_col - self.__start_col + 1
self.__elements[self.__start_row - 1 + row - 1][self.__start_col - 1 + col - 1] = value
Expand Down
34 changes: 20 additions & 14 deletions src/solutions/chapter4/problem7.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from util import range_of


def monge_leftmost_minimums(A: Matrix, m: int, n: int) -> Array[int | float]:
def monge_leftmost_minimums(A: Matrix, m: int, n: int) -> Array[int]:
"""Finds the leftmost minimum in each row of a Monge array.
Args:
Expand All @@ -18,20 +18,21 @@ def monge_leftmost_minimums(A: Matrix, m: int, n: int) -> Array[int | float]:
The array containing the leftmost minimums of A, ordered by rows.
"""
indices = __monge_leftmost_minimums_indices(A, m, n)
minimums = Array(1, m)
minimums = Array[int](1, m)
for i in range_of(1, to=m):
minimums[i] = A[i, indices[i]]
return minimums


def __monge_leftmost_minimums_indices(A: Matrix, m: int, n: int) -> Array[int] | None:
if m == 0:
return None
def __monge_leftmost_minimums_indices(A: Matrix, m: int, n: int) -> Array[int]:
indices = Array[int](1, m)
if m == 1:
indices[1] = __find_minimum_index(A, 1, 1, n)
return indices
A_ = A.even_rows_submatrix()
even_rows_leftmost_minimums_indices = __monge_leftmost_minimums_indices(A_, m // 2, n)
odd_rows_leftmost_minimums_indices = __monge_odd_rows_leftmost_minimums_indices(A, m, n,
even_rows_leftmost_minimums_indices)
indices = Array[int](1, m)
for i in range_of(1, to=m // 2):
indices[2 * i] = even_rows_leftmost_minimums_indices[i]
for i in range_of(1, to=ceil_div(m, 2)):
Expand All @@ -42,16 +43,21 @@ def __monge_leftmost_minimums_indices(A: Matrix, m: int, n: int) -> Array[int] |
def __monge_odd_rows_leftmost_minimums_indices(A: Matrix,
m: int,
n: int,
even_rows_leftmost_minimums_indices: Array[int])\
-> Array[int | float]:
even_rows_leftmost_minimums_indices: Array[int]) -> Array[int]:
odd_rows_leftmost_minimums_indices = Array(1, ceil_div(m, 2))
for i in range_of(1, to=ceil_div(m, 2)):
prev_minimum_index = even_rows_leftmost_minimums_indices[i - 1] if i > 1 else 1
next_minimum_index = even_rows_leftmost_minimums_indices[i] if i <= m // 2 else n
row_number = 2 * i - 1
minimum = None
for j in range_of(prev_minimum_index, to=next_minimum_index):
if minimum is None or A[row_number, j] < minimum:
minimum = A[row_number, j]
odd_rows_leftmost_minimums_indices[i] = j
odd_rows_leftmost_minimums_indices[i] = __find_minimum_index(A, 2 * i - 1, prev_minimum_index,
next_minimum_index)
return odd_rows_leftmost_minimums_indices


def __find_minimum_index(A: Matrix, row: int, col_start: int, col_end: int) -> int:
minimum = A[row, col_start]
index = col_start
for j in range_of(col_start + 1, to=col_end):
if A[row, j] < minimum:
minimum = A[row, j]
index = j
return index
2 changes: 1 addition & 1 deletion test/test_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def create_array(elements: list[T], start: int = 1) -> Array[T]:
return array


def create_matrix(elements: list[list[int | float]]) -> Matrix:
def create_matrix(elements: list[list[int]]) -> Matrix:
rows = len(elements)
cols = len(elements[0])
matrix = Matrix(rows, cols)
Expand Down

0 comments on commit b0e37f6

Please sign in to comment.