From b8fc4fe29401390b38d820672fb7f018152f5ea7 Mon Sep 17 00:00:00 2001 From: Truong Nhan Nguyen Date: Thu, 19 Sep 2024 20:13:10 +0700 Subject: [PATCH 01/10] ref: improve saddleback search --- src/searching/saddleback_search.rs | 135 +++++++++++++++++------------ 1 file changed, 81 insertions(+), 54 deletions(-) diff --git a/src/searching/saddleback_search.rs b/src/searching/saddleback_search.rs index 648d7fd3487..c61a1447cda 100644 --- a/src/searching/saddleback_search.rs +++ b/src/searching/saddleback_search.rs @@ -1,27 +1,32 @@ -// Saddleback search is a technique used to find an element in a sorted 2D matrix in O(m + n) time, -// where m is the number of rows, and n is the number of columns. It works by starting from the -// top-right corner of the matrix and moving left or down based on the comparison of the current -// element with the target element. use std::cmp::Ordering; -pub fn saddleback_search(matrix: &[Vec], element: i32) -> (usize, usize) { - // Initialize left and right indices +/// Performs Saddleback search on a sorted 2D matrix. +/// +/// The Saddleback search algorithm finds the position of a target element in a matrix where +/// each row and each column is sorted in ascending order. The search starts from the top-right +/// corner of the matrix and moves left or down based on comparisons with the target element. +/// +/// # Arguments +/// +/// * `matrix` - A 2D vector representing the sorted matrix. +/// * `element` - The target element to search for. +/// +/// # Returns +/// +/// Returns a tuple (row, column) where both indices are 1-based. If the element is not found, returns (0, 0). +pub fn saddleback_search(matrix: &[Vec], element: isize) -> (usize, usize) { let mut left_index = 0; let mut right_index = matrix[0].len() - 1; - // Start searching while left_index < matrix.len() { match element.cmp(&matrix[left_index][right_index]) { - // If the current element matches the target element, return its position (indices are 1-based) Ordering::Equal => return (left_index + 1, right_index + 1), Ordering::Greater => { - // If the target element is greater, move to the next row (downwards) left_index += 1; } Ordering::Less => { - // If the target element is smaller, move to the previous column (leftwards) if right_index == 0 { - break; // If we reach the left-most column, exit the loop + break; } else { right_index -= 1; } @@ -29,7 +34,6 @@ pub fn saddleback_search(matrix: &[Vec], element: i32) -> (usize, usize) { } } - // If the element is not found, return (0, 0) (0, 0) } @@ -37,49 +41,72 @@ pub fn saddleback_search(matrix: &[Vec], element: i32) -> (usize, usize) { mod tests { use super::*; - // Test when the element is not present in the matrix - #[test] - fn test_element_not_found() { - let matrix = vec![vec![1, 10, 100], vec![2, 20, 200], vec![3, 30, 300]]; - assert_eq!(saddleback_search(&matrix, 123), (0, 0)); - } - - // Test when the element is at the top-left corner of the matrix - #[test] - fn test_element_at_top_left() { - let matrix = vec![vec![1, 10, 100], vec![2, 20, 200], vec![3, 30, 300]]; - assert_eq!(saddleback_search(&matrix, 1), (1, 1)); - } - - // Test when the element is at the bottom-right corner of the matrix - #[test] - fn test_element_at_bottom_right() { - let matrix = vec![vec![1, 10, 100], vec![2, 20, 200], vec![3, 30, 300]]; - assert_eq!(saddleback_search(&matrix, 300), (3, 3)); - } - - // Test when the element is at the top-right corner of the matrix - #[test] - fn test_element_at_top_right() { - let matrix = vec![vec![1, 10, 100], vec![2, 20, 200], vec![3, 30, 300]]; - assert_eq!(saddleback_search(&matrix, 100), (1, 3)); - } - - // Test when the element is at the bottom-left corner of the matrix - #[test] - fn test_element_at_bottom_left() { - let matrix = vec![vec![1, 10, 100], vec![2, 20, 200], vec![3, 30, 300]]; - assert_eq!(saddleback_search(&matrix, 3), (3, 1)); + macro_rules! saddleback_tests { + ($($name:ident: $tc:expr,)*) => { + $( + #[test] + fn $name() { + let (matrix, element, expected) = $tc; + assert_eq!(saddleback_search(&matrix, element), expected); + } + )* + }; } - // Additional test case: Element in the middle of the matrix - #[test] - fn test_element_in_middle() { - let matrix = vec![ - vec![1, 10, 100, 1000], - vec![2, 20, 200, 2000], - vec![3, 30, 300, 3000], - ]; - assert_eq!(saddleback_search(&matrix, 200), (2, 3)); + saddleback_tests! { + test_element_not_found: ( + vec![ + vec![1, 10, 100], + vec![2, 20, 200], + vec![3, 30, 300] + ], + 123, + (0, 0), + ), + test_element_at_top_left: ( + vec![ + vec![1, 10, 100], + vec![2, 20, 200], + vec![3, 30, 300] + ], + 1, + (1, 1), + ), + test_element_at_bottom_right: ( + vec![ + vec![1, 10, 100], + vec![2, 20, 200], + vec![3, 30, 300] + ], + 300, + (3, 3), + ), + test_element_at_top_right: ( + vec![ + vec![1, 10, 100], + vec![2, 20, 200], + vec![3, 30, 300] + ], + 100, + (1, 3), + ), + test_element_at_bottom_left: ( + vec![ + vec![1, 10, 100], + vec![2, 20, 200], + vec![3, 30, 300] + ], + 3, + (3, 1), + ), + test_element_in_middle: ( + vec![ + vec![1, 10, 100, 1000], + vec![2, 20, 200, 2000], + vec![3, 30, 300, 3000], + ], + 200, + (2, 3), + ), } } From 4c31581220808737863082fca0aef30b4b17d137 Mon Sep 17 00:00:00 2001 From: Truong Nhan Nguyen Date: Thu, 17 Oct 2024 20:39:18 +0700 Subject: [PATCH 02/10] tests: add `test_element_smaller_than_min` the `break` statement executed when the search reaches the leftmost column without finding the target element --- src/searching/saddleback_search.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/searching/saddleback_search.rs b/src/searching/saddleback_search.rs index c61a1447cda..b89051c0477 100644 --- a/src/searching/saddleback_search.rs +++ b/src/searching/saddleback_search.rs @@ -108,5 +108,14 @@ mod tests { 200, (2, 3), ), + test_element_smaller_than_min: ( + vec![ + vec![1, 10, 100], + vec![2, 20, 200], + vec![3, 30, 300], + ], + 0, + (0, 0), + ), } } From b54a02b2065a8036425f5243f373859a2b6f3f62 Mon Sep 17 00:00:00 2001 From: Truong Nhan Nguyen Date: Sat, 19 Oct 2024 10:21:06 +0700 Subject: [PATCH 03/10] chore: return `Option<(usize, usize)>` --- src/searching/saddleback_search.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/searching/saddleback_search.rs b/src/searching/saddleback_search.rs index b89051c0477..f6bdc5957b2 100644 --- a/src/searching/saddleback_search.rs +++ b/src/searching/saddleback_search.rs @@ -13,14 +13,14 @@ use std::cmp::Ordering; /// /// # Returns /// -/// Returns a tuple (row, column) where both indices are 1-based. If the element is not found, returns (0, 0). -pub fn saddleback_search(matrix: &[Vec], element: isize) -> (usize, usize) { +/// Returns `Some((row, column))` where both indices are 1-based. If the element is not found, returns `None`. +pub fn saddleback_search(matrix: &[Vec], element: isize) -> Option<(usize, usize)> { let mut left_index = 0; let mut right_index = matrix[0].len() - 1; while left_index < matrix.len() { match element.cmp(&matrix[left_index][right_index]) { - Ordering::Equal => return (left_index + 1, right_index + 1), + Ordering::Equal => return Some((left_index + 1, right_index + 1)), Ordering::Greater => { left_index += 1; } @@ -34,7 +34,7 @@ pub fn saddleback_search(matrix: &[Vec], element: isize) -> (usize, usize } } - (0, 0) + None } #[cfg(test)] @@ -61,7 +61,7 @@ mod tests { vec![3, 30, 300] ], 123, - (0, 0), + None, ), test_element_at_top_left: ( vec![ @@ -70,7 +70,7 @@ mod tests { vec![3, 30, 300] ], 1, - (1, 1), + Some((1, 1)), ), test_element_at_bottom_right: ( vec![ @@ -79,7 +79,7 @@ mod tests { vec![3, 30, 300] ], 300, - (3, 3), + Some((3, 3)), ), test_element_at_top_right: ( vec![ @@ -88,7 +88,7 @@ mod tests { vec![3, 30, 300] ], 100, - (1, 3), + Some((1, 3)), ), test_element_at_bottom_left: ( vec![ @@ -97,7 +97,7 @@ mod tests { vec![3, 30, 300] ], 3, - (3, 1), + Some((3, 1)), ), test_element_in_middle: ( vec![ @@ -106,7 +106,7 @@ mod tests { vec![3, 30, 300, 3000], ], 200, - (2, 3), + Some((2, 3)), ), test_element_smaller_than_min: ( vec![ @@ -115,7 +115,7 @@ mod tests { vec![3, 30, 300], ], 0, - (0, 0), + None, ), } } From acc74d616a78e0c2e57b67b6b393016fe28a54f2 Mon Sep 17 00:00:00 2001 From: Truong Nhan Nguyen Date: Sat, 19 Oct 2024 10:24:50 +0700 Subject: [PATCH 04/10] chore: return zero-based index --- src/searching/saddleback_search.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/searching/saddleback_search.rs b/src/searching/saddleback_search.rs index f6bdc5957b2..0f08c6a261b 100644 --- a/src/searching/saddleback_search.rs +++ b/src/searching/saddleback_search.rs @@ -13,14 +13,14 @@ use std::cmp::Ordering; /// /// # Returns /// -/// Returns `Some((row, column))` where both indices are 1-based. If the element is not found, returns `None`. +/// Returns `Some((row, column))` where both indices are 0-based. If the element is not found, returns `None`. pub fn saddleback_search(matrix: &[Vec], element: isize) -> Option<(usize, usize)> { let mut left_index = 0; let mut right_index = matrix[0].len() - 1; while left_index < matrix.len() { match element.cmp(&matrix[left_index][right_index]) { - Ordering::Equal => return Some((left_index + 1, right_index + 1)), + Ordering::Equal => return Some((left_index, right_index)), Ordering::Greater => { left_index += 1; } @@ -61,7 +61,7 @@ mod tests { vec![3, 30, 300] ], 123, - None, + None::<(usize, usize)>, ), test_element_at_top_left: ( vec![ @@ -70,7 +70,7 @@ mod tests { vec![3, 30, 300] ], 1, - Some((1, 1)), + Some((0, 0)), ), test_element_at_bottom_right: ( vec![ @@ -79,7 +79,7 @@ mod tests { vec![3, 30, 300] ], 300, - Some((3, 3)), + Some((2, 2)), ), test_element_at_top_right: ( vec![ @@ -88,7 +88,7 @@ mod tests { vec![3, 30, 300] ], 100, - Some((1, 3)), + Some((0, 2)), ), test_element_at_bottom_left: ( vec![ @@ -97,7 +97,7 @@ mod tests { vec![3, 30, 300] ], 3, - Some((3, 1)), + Some((2, 0)), ), test_element_in_middle: ( vec![ @@ -106,7 +106,7 @@ mod tests { vec![3, 30, 300, 3000], ], 200, - Some((2, 3)), + Some((1, 2)), ), test_element_smaller_than_min: ( vec![ @@ -115,7 +115,7 @@ mod tests { vec![3, 30, 300], ], 0, - None, + None::<(usize, usize)>, ), } } From 95aa66e646107e435bbb8e31cb20819f77af63cd Mon Sep 17 00:00:00 2001 From: vil02 <65706193+vil02@users.noreply.github.com> Date: Sat, 19 Oct 2024 20:38:26 +0200 Subject: [PATCH 05/10] tests: verify test data --- src/searching/saddleback_search.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/searching/saddleback_search.rs b/src/searching/saddleback_search.rs index 0f08c6a261b..d93bd3c63e5 100644 --- a/src/searching/saddleback_search.rs +++ b/src/searching/saddleback_search.rs @@ -47,6 +47,9 @@ mod tests { #[test] fn $name() { let (matrix, element, expected) = $tc; + if let Some(expected_pos) = expected { + assert_eq!(matrix[expected_pos.0][expected_pos.1], element); + } assert_eq!(saddleback_search(&matrix, element), expected); } )* From f5f6179ce787bc82df0c8ac87cdec4c083802aa7 Mon Sep 17 00:00:00 2001 From: vil02 <65706193+vil02@users.noreply.github.com> Date: Sat, 19 Oct 2024 20:45:23 +0200 Subject: [PATCH 06/10] tests: add some edge cases --- src/searching/saddleback_search.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/searching/saddleback_search.rs b/src/searching/saddleback_search.rs index d93bd3c63e5..9a1d8aa639b 100644 --- a/src/searching/saddleback_search.rs +++ b/src/searching/saddleback_search.rs @@ -120,5 +120,28 @@ mod tests { 0, None::<(usize, usize)>, ), + test_horizontal: ( + vec![ + vec![1, 10, 100], + ], + 100, + Some((0, 2)), + ), + test_vertical: ( + vec![ + vec![1], + vec![2], + vec![3], + ], + 2, + Some((1, 0)), + ), + test_single_element: ( + vec![ + vec![1], + ], + 1, + Some((0, 0)), + ), } } From 78bd24230d1e8264eddc466b1548b3d7c5c20180 Mon Sep 17 00:00:00 2001 From: Truong Nhan Nguyen Date: Sun, 20 Oct 2024 09:49:42 +0700 Subject: [PATCH 07/10] ref: refactor implementation - Handle non-rectangular matrix - Handle cases of empty and full of empty rows matrix --- src/searching/saddleback_search.rs | 83 ++++++++++++++++++++++++------ 1 file changed, 66 insertions(+), 17 deletions(-) diff --git a/src/searching/saddleback_search.rs b/src/searching/saddleback_search.rs index 9a1d8aa639b..a79b28e0c09 100644 --- a/src/searching/saddleback_search.rs +++ b/src/searching/saddleback_search.rs @@ -1,5 +1,11 @@ use std::cmp::Ordering; +/// Custom error type to represent errors related to matrix validation. +#[derive(Debug, PartialEq, Eq)] +pub enum MatrixError { + NonRectangularMatrix, +} + /// Performs Saddleback search on a sorted 2D matrix. /// /// The Saddleback search algorithm finds the position of a target element in a matrix where @@ -13,14 +19,27 @@ use std::cmp::Ordering; /// /// # Returns /// -/// Returns `Some((row, column))` where both indices are 0-based. If the element is not found, returns `None`. -pub fn saddleback_search(matrix: &[Vec], element: isize) -> Option<(usize, usize)> { +/// Returns `Ok(Some((row, column)))` where both indices are 0-based if the element is found. +/// Returns `Ok(None)` if the element is not found. +/// Returns `Err(MatrixError)` if the matrix is not rectangular. +pub fn saddleback_search( + matrix: &[Vec], + element: isize, +) -> Result, MatrixError> { + if matrix.is_empty() || matrix.iter().all(|row| row.is_empty()) { + return Ok(None); + } + + if matrix.iter().any(|row| row.len() != matrix[0].len()) { + return Err(MatrixError::NonRectangularMatrix); + } + let mut left_index = 0; let mut right_index = matrix[0].len() - 1; while left_index < matrix.len() { match element.cmp(&matrix[left_index][right_index]) { - Ordering::Equal => return Some((left_index, right_index)), + Ordering::Equal => return Ok(Some((left_index, right_index))), Ordering::Greater => { left_index += 1; } @@ -34,7 +53,7 @@ pub fn saddleback_search(matrix: &[Vec], element: isize) -> Option<(usize } } - None + Ok(None) } #[cfg(test)] @@ -47,9 +66,6 @@ mod tests { #[test] fn $name() { let (matrix, element, expected) = $tc; - if let Some(expected_pos) = expected { - assert_eq!(matrix[expected_pos.0][expected_pos.1], element); - } assert_eq!(saddleback_search(&matrix, element), expected); } )* @@ -64,7 +80,7 @@ mod tests { vec![3, 30, 300] ], 123, - None::<(usize, usize)>, + Ok(None::<(usize, usize)>), ), test_element_at_top_left: ( vec![ @@ -73,7 +89,7 @@ mod tests { vec![3, 30, 300] ], 1, - Some((0, 0)), + Ok(Some((0, 0))), ), test_element_at_bottom_right: ( vec![ @@ -82,7 +98,7 @@ mod tests { vec![3, 30, 300] ], 300, - Some((2, 2)), + Ok(Some((2, 2))), ), test_element_at_top_right: ( vec![ @@ -91,7 +107,7 @@ mod tests { vec![3, 30, 300] ], 100, - Some((0, 2)), + Ok(Some((0, 2))), ), test_element_at_bottom_left: ( vec![ @@ -100,7 +116,7 @@ mod tests { vec![3, 30, 300] ], 3, - Some((2, 0)), + Ok(Some((2, 0))), ), test_element_in_middle: ( vec![ @@ -109,7 +125,7 @@ mod tests { vec![3, 30, 300, 3000], ], 200, - Some((1, 2)), + Ok(Some((1, 2))), ), test_element_smaller_than_min: ( vec![ @@ -118,14 +134,14 @@ mod tests { vec![3, 30, 300], ], 0, - None::<(usize, usize)>, + Ok(None::<(usize, usize)>), ), test_horizontal: ( vec![ vec![1, 10, 100], ], 100, - Some((0, 2)), + Ok(Some((0, 2))), ), test_vertical: ( vec![ @@ -134,14 +150,47 @@ mod tests { vec![3], ], 2, - Some((1, 0)), + Ok(Some((1, 0))), ), test_single_element: ( vec![ vec![1], ], 1, - Some((0, 0)), + Ok(Some((0, 0))), + ), + test_empty_matrix: ( + vec![], + 1, + Ok(None::<(usize, usize)>), + ), + test_non_rectangular_matrix: ( + vec![ + vec![1, 10, 100], + vec![2, 20], + vec![3, 30, 300], + ], + 20, + Err::, MatrixError>(MatrixError::NonRectangularMatrix), + ), + test_empty_row: ( + vec![ + vec![1, 2, 3], + vec![], + vec![4, 5, 6], + ], + 3, + Err::, MatrixError>(MatrixError::NonRectangularMatrix), + ), + test_full_empty_rows: ( + vec![ + vec![], + vec![], + vec![], + vec![], + ], + 1, + Ok(None::<(usize, usize)>), ), } } From 1fb90239716e87f205d8e040e14f88ccbc7b32b6 Mon Sep 17 00:00:00 2001 From: Truong Nhan Nguyen Date: Thu, 24 Oct 2024 20:28:54 +0700 Subject: [PATCH 08/10] ref: let saddleback search check if the input is sorted --- src/searching/saddleback_search.rs | 75 ++++++++++++++++++++++++++---- 1 file changed, 67 insertions(+), 8 deletions(-) diff --git a/src/searching/saddleback_search.rs b/src/searching/saddleback_search.rs index a79b28e0c09..3a3eea2c4a3 100644 --- a/src/searching/saddleback_search.rs +++ b/src/searching/saddleback_search.rs @@ -3,35 +3,85 @@ use std::cmp::Ordering; /// Custom error type to represent errors related to matrix validation. #[derive(Debug, PartialEq, Eq)] pub enum MatrixError { - NonRectangularMatrix, + NonRectangularInput, + NotSorted, } -/// Performs Saddleback search on a sorted 2D matrix. +/// Checks if the given matrix (vector of vectors) is sorted row-wise and column-wise. +/// +/// A matrix is considered sorted if +/// +/// * Each row is sorted in non-decreasing order. +/// * Each column is sorted in non-decreasing order. +/// +/// # Arguments +/// +/// * `matrix` - A vector of vectors representing the matrix to check. +/// +/// # Returns +/// +/// Returns `true` if the matrix is sorted both row-wise and column-wise. Otherwise, returns `false`. +fn is_sorted(matrix: &[Vec]) -> bool { + if matrix.is_empty() || matrix.iter().all(|row| row.is_empty()) { + return true; + } + + let rows = matrix.len(); + let cols = matrix[0].len(); + + // Check if rows are sorted. + for row in matrix { + if row.windows(2).any(|w| w[0] > w[1]) { + return false; + } + } + + // Check if columns are sorted. + for col in 0..cols { + for row in 1..rows { + if matrix[row - 1][col] > matrix[row][col] { + return false; + } + } + } + + true +} + +/// Performs Saddleback search on a sorted matrix represented as a vector of vectors. /// /// The Saddleback search algorithm finds the position of a target element in a matrix where /// each row and each column is sorted in ascending order. The search starts from the top-right /// corner of the matrix and moves left or down based on comparisons with the target element. /// +/// Optionally, the matrix can be validated for being sorted before the search starts. +/// /// # Arguments /// -/// * `matrix` - A 2D vector representing the sorted matrix. +/// * `matrix` - A vector of vectors representing the sorted matrix. /// * `element` - The target element to search for. +/// * `check_sorted` - If true, verifies that the matrix is sorted before performing the search. /// /// # Returns /// /// Returns `Ok(Some((row, column)))` where both indices are 0-based if the element is found. /// Returns `Ok(None)` if the element is not found. -/// Returns `Err(MatrixError)` if the matrix is not rectangular. +/// Returns `Err(MatrixError)` if the matrix is not rectangular or not sorted. pub fn saddleback_search( matrix: &[Vec], element: isize, + check_sorted: bool, ) -> Result, MatrixError> { if matrix.is_empty() || matrix.iter().all(|row| row.is_empty()) { return Ok(None); } if matrix.iter().any(|row| row.len() != matrix[0].len()) { - return Err(MatrixError::NonRectangularMatrix); + return Err(MatrixError::NonRectangularInput); + } + + if check_sorted && !is_sorted(matrix) { + return Err(MatrixError::NotSorted); } let mut left_index = 0; @@ -66,7 +116,7 @@ mod tests { #[test] fn $name() { let (matrix, element, expected) = $tc; - assert_eq!(saddleback_search(&matrix, element), expected); + assert_eq!(saddleback_search(&matrix, element, true), expected); } )* }; @@ -171,7 +221,7 @@ mod tests { vec![3, 30, 300], ], 20, - Err::, MatrixError>(MatrixError::NonRectangularMatrix), + Err::, MatrixError>(MatrixError::NonRectangularInput), ), test_empty_row: ( vec![ @@ -180,7 +230,7 @@ mod tests { vec![4, 5, 6], ], 3, - Err::, MatrixError>(MatrixError::NonRectangularMatrix), + Err::, MatrixError>(MatrixError::NonRectangularInput), ), test_full_empty_rows: ( vec![ @@ -192,5 +242,14 @@ mod tests { 1, Ok(None::<(usize, usize)>), ), + test_unsorted_matrix_with_check: ( + vec![ + vec![1, 10, 100], + vec![20, 200, 2], + vec![3, 30, 300], + ], + 200, + Err::, MatrixError>(MatrixError::NotSorted), + ), } } From 4436d2cf593a4235d2ea7a9fb37ed2b3e81bf52e Mon Sep 17 00:00:00 2001 From: Truong Nhan Nguyen Date: Thu, 24 Oct 2024 20:55:11 +0700 Subject: [PATCH 09/10] test: add some edge tests --- src/searching/saddleback_search.rs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/searching/saddleback_search.rs b/src/searching/saddleback_search.rs index 3a3eea2c4a3..1aaa4ebf795 100644 --- a/src/searching/saddleback_search.rs +++ b/src/searching/saddleback_search.rs @@ -72,6 +72,10 @@ pub fn saddleback_search( element: isize, check_sorted: bool, ) -> Result, MatrixError> { + if check_sorted && !is_sorted(matrix) { + return Err(MatrixError::NotSorted); + } + if matrix.is_empty() || matrix.iter().all(|row| row.is_empty()) { return Ok(None); } @@ -80,10 +84,6 @@ pub fn saddleback_search( return Err(MatrixError::NonRectangularInput); } - if check_sorted && !is_sorted(matrix) { - return Err(MatrixError::NotSorted); - } - let mut left_index = 0; let mut right_index = matrix[0].len() - 1; @@ -242,7 +242,7 @@ mod tests { 1, Ok(None::<(usize, usize)>), ), - test_unsorted_matrix_with_check: ( + test_unsorted_matrix_row_wise: ( vec![ vec![1, 10, 100], vec![20, 200, 2], @@ -251,5 +251,14 @@ mod tests { 200, Err::, MatrixError>(MatrixError::NotSorted), ), + test_unsorted_matrix_column_wise: ( + vec![ + vec![1, 10, 100], + vec![2, 20, 30], + vec![3, 15, 300], + ], + 200, + Err::, MatrixError>(MatrixError::NotSorted), + ), } } From 9b15298d34a9d05018fe15a6b3363bf661d11876 Mon Sep 17 00:00:00 2001 From: Truong Nhan Nguyen Date: Thu, 24 Oct 2024 21:02:18 +0700 Subject: [PATCH 10/10] ref: remove unneed check for empty matrix --- src/searching/saddleback_search.rs | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/src/searching/saddleback_search.rs b/src/searching/saddleback_search.rs index 1aaa4ebf795..b6bf9af0082 100644 --- a/src/searching/saddleback_search.rs +++ b/src/searching/saddleback_search.rs @@ -9,11 +9,6 @@ pub enum MatrixError { /// Checks if the given matrix (vector of vectors) is sorted row-wise and column-wise. /// -/// A matrix is considered sorted if -/// -/// * Each row is sorted in non-decreasing order. -/// * Each column is sorted in non-decreasing order. -/// /// # Arguments /// /// * `matrix` - A vector of vectors representing the matrix to check. @@ -22,10 +17,6 @@ pub enum MatrixError { /// /// Returns `true` if the matrix is sorted both row-wise and column-wise. Otherwise, returns `false`. fn is_sorted(matrix: &[Vec]) -> bool { - if matrix.is_empty() || matrix.iter().all(|row| row.is_empty()) { - return true; - } - let rows = matrix.len(); let cols = matrix[0].len(); @@ -72,10 +63,6 @@ pub fn saddleback_search( element: isize, check_sorted: bool, ) -> Result, MatrixError> { - if check_sorted && !is_sorted(matrix) { - return Err(MatrixError::NotSorted); - } - if matrix.is_empty() || matrix.iter().all(|row| row.is_empty()) { return Ok(None); } @@ -84,6 +71,10 @@ pub fn saddleback_search( return Err(MatrixError::NonRectangularInput); } + if check_sorted && !is_sorted(matrix) { + return Err(MatrixError::NotSorted); + } + let mut left_index = 0; let mut right_index = matrix[0].len() - 1;