Skip to content

Commit a1e8c60

Browse files
committed
feat: add custom error types
1 parent c98744f commit a1e8c60

File tree

1 file changed

+56
-19
lines changed

1 file changed

+56
-19
lines changed

src/dynamic_programming/minimum_cost_path.rs

Lines changed: 56 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,46 @@
11
use std::cmp::min;
22

3+
/// Represents possible errors that can occur when calculating the minimum cost path in a matrix.
4+
#[derive(Debug, PartialEq, Eq)]
5+
pub enum MatrixError {
6+
/// Error indicating that the matrix is empty or has empty rows.
7+
EmptyMatrix,
8+
/// Error indicating that the matrix is not rectangular in shape.
9+
NonRectangularMatrix,
10+
}
11+
312
/// Computes the minimum cost path from the top-left to the bottom-right
413
/// corner of a matrix, where movement is restricted to right and down directions.
514
///
6-
/// The function calculates the minimum path cost by updating a `cost` vector that
7-
/// stores cumulative path costs for the current row as it iterates through each
8-
/// row of the input `matrix`.
9-
///
1015
/// # Arguments
1116
///
1217
/// * `matrix` - A 2D vector of positive integers, where each element represents
1318
/// the cost to step on that cell.
1419
///
1520
/// # Returns
1621
///
17-
/// * A single `usize` value representing the minimum path cost to reach the
18-
/// bottom-right corner from the top-left corner of the matrix.
22+
/// * `Ok(usize)` - The minimum path cost to reach the bottom-right corner from
23+
/// the top-left corner of the matrix.
24+
/// * `Err(MatrixError)` - An error if the matrix is empty or improperly formatted.
1925
///
2026
/// # Complexity
2127
///
2228
/// * Time complexity: `O(m * n)`, where `m` is the number of rows
2329
/// and `n` is the number of columns in the input matrix.
2430
/// * Space complexity: `O(n)`, as only a single row of cumulative costs
2531
/// is stored at any time.
26-
pub fn minimum_cost_path(matrix: Vec<Vec<usize>>) -> usize {
27-
// Initialize the first row of the cost vector using a scan over the first row of matrix
32+
pub fn minimum_cost_path(matrix: Vec<Vec<usize>>) -> Result<usize, MatrixError> {
33+
// Check if the matrix is rectangular
34+
if !matrix.iter().all(|row| row.len() == matrix[0].len()) {
35+
return Err(MatrixError::NonRectangularMatrix);
36+
}
37+
38+
// Check if the matrix is empty or contains empty rows
39+
if matrix.is_empty() || matrix.iter().all(|row| row.is_empty()) {
40+
return Err(MatrixError::EmptyMatrix);
41+
}
42+
43+
// Initialize the first row of the cost vector
2844
let mut cost = matrix[0]
2945
.iter()
3046
.scan(0, |acc, &val| {
@@ -45,7 +61,7 @@ pub fn minimum_cost_path(matrix: Vec<Vec<usize>>) -> usize {
4561
}
4662

4763
// The last element in cost contains the minimum path cost to the bottom-right corner
48-
cost[matrix[0].len() - 1]
64+
Ok(cost[matrix[0].len() - 1])
4965
}
5066

5167
#[cfg(test)]
@@ -71,28 +87,29 @@ mod tests {
7187
vec![2, 1, 3],
7288
vec![3, 2, 1]
7389
],
74-
7
90+
Ok(7)
7591
),
7692
single_element: (
7793
vec![
7894
vec![5]
7995
],
80-
5
96+
Ok(5)
8197
),
8298
single_row: (
8399
vec![
84100
vec![1, 3, 2, 1, 5]
85101
],
86-
12
102+
Ok(12)
87103
),
88104
single_column: (
89105
vec![
90106
vec![1],
91107
vec![3],
92108
vec![2],
93109
vec![1],
94-
vec![5]],
95-
12
110+
vec![5]
111+
],
112+
Ok(12)
96113
),
97114
large_matrix: (
98115
vec![
@@ -101,31 +118,31 @@ mod tests {
101118
vec![3, 2, 1, 3],
102119
vec![4, 3, 2, 1]
103120
],
104-
10
121+
Ok(10)
105122
),
106123
uniform_matrix: (
107124
vec![
108125
vec![1, 1, 1],
109126
vec![1, 1, 1],
110127
vec![1, 1, 1]
111128
],
112-
5
129+
Ok(5)
113130
),
114131
increasing_values: (
115132
vec![
116133
vec![1, 2, 3],
117134
vec![4, 5, 6],
118135
vec![7, 8, 9]
119136
],
120-
21
137+
Ok(21)
121138
),
122139
high_cost_path: (
123140
vec![
124141
vec![1, 100, 1],
125142
vec![1, 100, 1],
126143
vec![1, 1, 1]
127144
],
128-
5
145+
Ok(5)
129146
),
130147
complex_matrix: (
131148
vec![
@@ -134,7 +151,27 @@ mod tests {
134151
vec![2, 1, 8, 2],
135152
vec![3, 6, 9, 4]
136153
],
137-
23
154+
Ok(23)
155+
),
156+
empty_matrix: (
157+
vec![],
158+
Err(MatrixError::EmptyMatrix)
159+
),
160+
empty_row: (
161+
vec![
162+
vec![],
163+
vec![],
164+
vec![]
165+
],
166+
Err(MatrixError::EmptyMatrix)
167+
),
168+
non_rectangular: (
169+
vec![
170+
vec![1, 2, 3],
171+
vec![4, 5],
172+
vec![6, 7, 8]
173+
],
174+
Err(MatrixError::NonRectangularMatrix)
138175
),
139176
}
140177
}

0 commit comments

Comments
 (0)