diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 2df5673a3d9..3623445a8c7 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -20,6 +20,7 @@ Please delete options that are not relevant. - [ ] I ran `cargo clippy --all -- -D warnings` just before my last commit and fixed any issue that was found. - [ ] I ran `cargo fmt` just before my last commit. - [ ] I ran `cargo test` just before my last commit and all tests passed. +- [ ] I added my algorithm to the corresponding `mod.rs` file within its own folder, and in any parent folder(s). - [ ] I added my algorithm to `DIRECTORY.md` with the correct link. - [ ] I checked `COUNTRIBUTING.md` and my code follows its guidelines. diff --git a/src/ciphers/baconian_cipher.rs b/src/ciphers/baconian_cipher.rs index 46dfb40a0ee..0ae71cab2cf 100644 --- a/src/ciphers/baconian_cipher.rs +++ b/src/ciphers/baconian_cipher.rs @@ -4,9 +4,8 @@ // Bacon's cipher or the Baconian cipher is a method of steganographic message encoding devised by Francis Bacon in 1605. // A message is concealed in the presentation of text, rather than its content. Bacon cipher is categorized as both a substitution cipher (in plain code) and a concealment cipher (using the two typefaces). - // Encode Baconian Cipher -fn baconian_encode(message: &str) -> String { +pub fn baconian_encode(message: &str) -> String { let alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; let baconian = [ "AAAAA", "AAAAB", "AAABA", "AAABB", "AABAA", "AABAB", "AABBA", "AABBB", "ABAAA", "ABAAB", @@ -18,7 +17,7 @@ fn baconian_encode(message: &str) -> String { .chars() .map(|c| { if let Some(index) = alphabet.find(c.to_ascii_uppercase()) { - baconian[index as usize].to_string() + baconian[index].to_string() } else { c.to_string() } @@ -26,9 +25,8 @@ fn baconian_encode(message: &str) -> String { .collect() } - // Decode Baconian Cipher -fn baconian_decode(encoded: &str) -> String { +pub fn baconian_decode(encoded: &str) -> String { let baconian = [ "AAAAA", "AAAAB", "AAABA", "AAABB", "AABAA", "AABAB", "AABBA", "AABBB", "ABAAA", "ABAAB", "ABABA", "ABABB", "ABBAA", "ABBAB", "ABBBA", "ABBBB", "BAAAA", "BAAAB", "BAABA", "BAABB", @@ -40,7 +38,10 @@ fn baconian_decode(encoded: &str) -> String { .as_bytes() .chunks(5) .map(|chunk| { - if let Some(index) = baconian.iter().position(|&x| x == String::from_utf8_lossy(chunk)) { + if let Some(index) = baconian + .iter() + .position(|&x| x == String::from_utf8_lossy(chunk)) + { alphabet.chars().nth(index).unwrap() } else { ' ' diff --git a/src/ciphers/mod.rs b/src/ciphers/mod.rs index 1bbc81418d7..f7a55b0014d 100644 --- a/src/ciphers/mod.rs +++ b/src/ciphers/mod.rs @@ -1,5 +1,6 @@ mod aes; mod another_rot13; +mod baconian_cipher; mod base64; mod blake2b; mod caesar; @@ -21,6 +22,7 @@ mod vigenere; mod xor; pub use self::aes::{aes_decrypt, aes_encrypt, AesKey}; pub use self::another_rot13::another_rot13; +pub use self::baconian_cipher::{baconian_decode, baconian_encode}; pub use self::base64::{base64_decode, base64_encode}; pub use self::blake2b::blake2b; pub use self::caesar::caesar; diff --git a/src/conversions/binary_to_hexadecimal.rs b/src/conversions/binary_to_hexadecimal.rs index 704e00f9153..08220eaa780 100644 --- a/src/conversions/binary_to_hexadecimal.rs +++ b/src/conversions/binary_to_hexadecimal.rs @@ -22,7 +22,7 @@ static BITS_TO_HEX: &[(u8, &str)] = &[ (0b1111, "f"), ]; -fn bin_to_hexadecimal(binary_str: &str) -> String { +pub fn binary_to_hexadecimal(binary_str: &str) -> String { let binary_str = binary_str.trim(); if binary_str.is_empty() { @@ -41,7 +41,11 @@ fn bin_to_hexadecimal(binary_str: &str) -> String { } let padded_len = (4 - (binary_str.len() % 4)) % 4; - let binary_str = format!("{:0width$}", binary_str, width = binary_str.len() + padded_len); + let binary_str = format!( + "{:0width$}", + binary_str, + width = binary_str.len() + padded_len + ); // Convert binary to hexadecimal let mut hexadecimal = String::with_capacity(binary_str.len() / 4 + 2); @@ -50,7 +54,7 @@ fn bin_to_hexadecimal(binary_str: &str) -> String { for chunk in binary_str.as_bytes().chunks(4) { let mut nibble = 0; for (i, &byte) in chunk.iter().enumerate() { - nibble |= ((byte - b'0') as u8) << (3 - i); + nibble |= (byte - b'0') << (3 - i); } let hex_char = BITS_TO_HEX @@ -76,27 +80,27 @@ mod tests { fn test_empty_string() { let input = ""; let expected = "Invalid Input"; - assert_eq!(bin_to_hexadecimal(input), expected); + assert_eq!(binary_to_hexadecimal(input), expected); } #[test] fn test_invalid_binary() { let input = "a"; let expected = "Invalid Input"; - assert_eq!(bin_to_hexadecimal(input), expected); + assert_eq!(binary_to_hexadecimal(input), expected); } #[test] fn test_binary() { let input = "00110110"; let expected = "0x36"; - assert_eq!(bin_to_hexadecimal(input), expected); + assert_eq!(binary_to_hexadecimal(input), expected); } #[test] fn test_padded_binary() { let input = " 1010 "; let expected = "0xa"; - assert_eq!(bin_to_hexadecimal(input), expected); + assert_eq!(binary_to_hexadecimal(input), expected); } } diff --git a/src/conversions/hexadecimal_to_binary.rs b/src/conversions/hexadecimal_to_binary.rs index 9c85daa6acb..490b69e8fb0 100644 --- a/src/conversions/hexadecimal_to_binary.rs +++ b/src/conversions/hexadecimal_to_binary.rs @@ -4,7 +4,7 @@ // 2. https://en.wikipedia.org/wiki/Binary_number // Other References for Testing : https://www.rapidtables.com/convert/number/hex-to-binary.html -fn hexadecimal_to_binary(hex_str: &str) -> Result { +pub fn hexadecimal_to_binary(hex_str: &str) -> Result { let hex_chars = hex_str.chars().collect::>(); let mut binary = String::new(); diff --git a/src/conversions/mod.rs b/src/conversions/mod.rs index 4ce36e015dd..fd39ed9d2a2 100644 --- a/src/conversions/mod.rs +++ b/src/conversions/mod.rs @@ -1,4 +1,10 @@ mod binary_to_decimal; +mod binary_to_hexadecimal; mod decimal_to_binary; +mod hexadecimal_to_binary; +mod octal_to_binary; pub use self::binary_to_decimal::binary_to_decimal; +pub use self::binary_to_hexadecimal::binary_to_hexadecimal; pub use self::decimal_to_binary::decimal_to_binary; +pub use self::hexadecimal_to_binary::hexadecimal_to_binary; +pub use self::octal_to_binary::octal_to_binary; diff --git a/src/conversions/octal_to_binary.rs b/src/conversions/octal_to_binary.rs index db150809046..ba4a9ccebd2 100644 --- a/src/conversions/octal_to_binary.rs +++ b/src/conversions/octal_to_binary.rs @@ -3,14 +3,14 @@ // Wikipedia References : 1. https://en.wikipedia.org/wiki/Octal // 2. https://en.wikipedia.org/wiki/Binary_number -fn octal_to_binary(octal_str: &str) -> Result { +pub fn octal_to_binary(octal_str: &str) -> Result { let octal_str = octal_str.trim(); if octal_str.is_empty() { return Err("Empty"); } - if !octal_str.chars().all(|c| c >= '0' && c <= '7') { + if !octal_str.chars().all(|c| ('0'..'7').contains(&c)) { return Err("Non-octal Value"); } @@ -54,8 +54,7 @@ mod tests { #[test] fn test_valid_octal() { let input = "123"; - let expected = Ok("001010011".to_string()); + let expected = Ok("001010011".to_string()); assert_eq!(octal_to_binary(input), expected); } - } diff --git a/src/data_structures/floyds_algorithm.rs b/src/data_structures/floyds_algorithm.rs index f75b76c659d..4ef9b4a6c3e 100644 --- a/src/data_structures/floyds_algorithm.rs +++ b/src/data_structures/floyds_algorithm.rs @@ -49,11 +49,9 @@ pub fn has_cycle(linked_list: &LinkedList) -> bool { } if slow == fast { - return true; // Cycle detected } } - } // println!("{}", flag); false // No cycle detected @@ -70,7 +68,7 @@ mod tests { linked_list.insert_at_tail(2); linked_list.insert_at_tail(3); - assert_eq!(has_cycle(&linked_list), false); + assert!(!has_cycle(&linked_list)); assert_eq!(detect_cycle(&mut linked_list), None); } @@ -91,7 +89,7 @@ mod tests { } } - assert_eq!(has_cycle(&linked_list), true); + assert!(has_cycle(&linked_list)); assert_eq!(detect_cycle(&mut linked_list), Some(3)); } } diff --git a/src/data_structures/infix_to_postfix.rs b/src/data_structures/infix_to_postfix.rs index 1c0a5996c6b..8d1ca6e7922 100755 --- a/src/data_structures/infix_to_postfix.rs +++ b/src/data_structures/infix_to_postfix.rs @@ -1,5 +1,5 @@ // Function to convert infix expression to postfix expression -fn infix_to_postfix(infix: &str) -> String { +pub fn infix_to_postfix(infix: &str) -> String { let mut postfix = String::new(); let mut stack: Vec = Vec::new(); @@ -53,17 +53,13 @@ fn infix_to_postfix(infix: &str) -> String { postfix } - #[cfg(test)] mod tests { use super::*; #[test] fn test_infix_to_postfix() { - assert_eq!( - infix_to_postfix("a-b+c-d*e"), - "ab-c+de*-".to_string() - ); + assert_eq!(infix_to_postfix("a-b+c-d*e"), "ab-c+de*-".to_string()); assert_eq!( infix_to_postfix("a*(b+c)+d/(e+f)"), "abc+*def+/+".to_string() diff --git a/src/data_structures/mod.rs b/src/data_structures/mod.rs index 527bf5a0a99..6e5a66b8232 100644 --- a/src/data_structures/mod.rs +++ b/src/data_structures/mod.rs @@ -2,10 +2,13 @@ mod avl_tree; mod b_tree; mod binary_search_tree; mod fenwick_tree; +mod floyds_algorithm; mod graph; mod heap; +mod infix_to_postfix; mod lazy_segment_tree; mod linked_list; +mod postfix_evaluation; mod probabilistic; mod queue; mod rb_tree; @@ -21,11 +24,14 @@ pub use self::avl_tree::AVLTree; pub use self::b_tree::BTree; pub use self::binary_search_tree::BinarySearchTree; pub use self::fenwick_tree::FenwickTree; +pub use self::floyds_algorithm::{detect_cycle, has_cycle}; pub use self::graph::DirectedGraph; pub use self::graph::UndirectedGraph; pub use self::heap::Heap; +pub use self::infix_to_postfix::infix_to_postfix; pub use self::lazy_segment_tree::LazySegmentTree; pub use self::linked_list::LinkedList; +pub use self::postfix_evaluation::evaluate_postfix; pub use self::probabilistic::bloom_filter; pub use self::probabilistic::count_min_sketch; pub use self::queue::Queue; diff --git a/src/data_structures/postfix_evaluation.rs b/src/data_structures/postfix_evaluation.rs index cee47d1550f..485c83e9526 100644 --- a/src/data_structures/postfix_evaluation.rs +++ b/src/data_structures/postfix_evaluation.rs @@ -1,4 +1,4 @@ -fn evaluate_postfix(expression: &str) -> Result { +pub fn evaluate_postfix(expression: &str) -> Result { let mut stack: Vec = Vec::new(); for token in expression.split_whitespace() { @@ -56,4 +56,3 @@ mod tests { assert_eq!(evaluate_postfix("5 0 /"), Err("Division by zero")); } } - diff --git a/src/general/kadane_algorithm.rs b/src/general/kadane_algorithm.rs index 07fdd59947b..a7452b62d23 100644 --- a/src/general/kadane_algorithm.rs +++ b/src/general/kadane_algorithm.rs @@ -18,7 +18,7 @@ * @param arr A slice of integers representing the array. * @return The maximum subarray sum. */ - fn max_sub_array(nums: Vec) -> i32 { +pub fn max_sub_array(nums: Vec) -> i32 { if nums.is_empty() { return 0; } @@ -26,13 +26,13 @@ let mut max_current = nums[0]; let mut max_global = nums[0]; - for i in 1..nums.len() { - max_current = std::cmp::max(nums[i], max_current + nums[i]); + nums.iter().skip(1).for_each(|&item| { + max_current = std::cmp::max(item, max_current + item); if max_current > max_global { max_global = max_current; } - } - return max_global; + }); + max_global } #[cfg(test)] diff --git a/src/general/mod.rs b/src/general/mod.rs index b839969e70c..3572b146f4a 100644 --- a/src/general/mod.rs +++ b/src/general/mod.rs @@ -3,6 +3,7 @@ mod fisher_yates_shuffle; mod genetic; mod hanoi; mod huffman_encoding; +mod kadane_algorithm; mod kmeans; mod mex; mod permutations; @@ -13,6 +14,7 @@ pub use self::fisher_yates_shuffle::fisher_yates_shuffle; pub use self::genetic::GeneticAlgorithm; pub use self::hanoi::hanoi; pub use self::huffman_encoding::{HuffmanDictionary, HuffmanEncoding}; +pub use self::kadane_algorithm::max_sub_array; pub use self::kmeans::f32::kmeans as kmeans_f32; pub use self::kmeans::f64::kmeans as kmeans_f64; pub use self::mex::mex_using_set; diff --git a/src/machine_learning/mod.rs b/src/machine_learning/mod.rs index eca1ac123bc..3ed46ab7864 100644 --- a/src/machine_learning/mod.rs +++ b/src/machine_learning/mod.rs @@ -3,9 +3,7 @@ mod loss_function; mod optimization; pub use self::linear_regression::linear_regression; - pub use self::loss_function::mae_loss; pub use self::loss_function::mse_loss; - pub use self::optimization::gradient_descent; pub use self::optimization::Adam; diff --git a/src/machine_learning/optimization/mod.rs b/src/machine_learning/optimization/mod.rs index 623508955aa..7a962993beb 100644 --- a/src/machine_learning/optimization/mod.rs +++ b/src/machine_learning/optimization/mod.rs @@ -1,6 +1,5 @@ -mod gradient_descent; - mod adam; +mod gradient_descent; pub use self::adam::Adam; pub use self::gradient_descent::gradient_descent; diff --git a/src/math/area_of_polygon.rs b/src/math/area_of_polygon.rs index 1158be39a38..3388c9f4267 100644 --- a/src/math/area_of_polygon.rs +++ b/src/math/area_of_polygon.rs @@ -14,7 +14,7 @@ * @see [Wikipedia - Polygon](https://en.wikipedia.org/wiki/Polygon) */ - struct Point { +pub struct Point { x: f64, y: f64, } @@ -25,7 +25,7 @@ * @return The area of the polygon. */ -fn area(fig: &Vec) -> f64 { +pub fn area_of_polygon(fig: &Vec) -> f64 { let mut res = 0.0; for i in 0..fig.len() { @@ -57,7 +57,7 @@ mod tests { Point { x: 0.0, y: 1.0 }, ]; - assert_eq!(area(&points), 0.5); + assert_eq!(area_of_polygon(&points), 0.5); } /** @@ -72,7 +72,7 @@ mod tests { Point { x: 0.0, y: 1.0 }, ]; - assert_eq!(area(&points), 1.0); + assert_eq!(area_of_polygon(&points), 1.0); } /** @@ -89,6 +89,6 @@ mod tests { Point { x: -0.5, y: 0.866 }, ]; - assert_eq!(area(&points), 2.598); + assert_eq!(area_of_polygon(&points), 2.598); } } diff --git a/src/math/area_under_curve.rs b/src/math/area_under_curve.rs index a8d33f096af..fe228db0119 100644 --- a/src/math/area_under_curve.rs +++ b/src/math/area_under_curve.rs @@ -1,4 +1,4 @@ -fn area_under_curve(start: f64, end: f64, func: fn(f64) -> f64, step_count: usize) -> f64 { +pub fn area_under_curve(start: f64, end: f64, func: fn(f64) -> f64, step_count: usize) -> f64 { assert!(step_count > 0); let (start, end) = if start > end { diff --git a/src/math/catalan_numbers.rs b/src/math/catalan_numbers.rs index cd4c175780c..4aceec3289e 100644 --- a/src/math/catalan_numbers.rs +++ b/src/math/catalan_numbers.rs @@ -12,7 +12,7 @@ const MOD: i64 = 1000000007; // Define your MOD value here const MAX: usize = 1005; // Define your MAX value here -fn init() -> Vec { +pub fn init_catalan() -> Vec { let mut catalan = vec![0; MAX]; catalan[0] = 1; catalan[1] = 1; @@ -36,7 +36,7 @@ mod tests { #[test] fn test_catalan() { - let catalan = init(); + let catalan = init_catalan(); // Test case 1: Catalan number for n = 0 assert_eq!(catalan[0], 1); diff --git a/src/math/mod.rs b/src/math/mod.rs index 438121df8b6..338e8df8de1 100644 --- a/src/math/mod.rs +++ b/src/math/mod.rs @@ -1,12 +1,15 @@ mod abs; mod aliquot_sum; mod amicable_numbers; +mod area_of_polygon; +mod area_under_curve; mod armstrong_number; mod average; mod baby_step_giant_step; mod bell_numbers; mod binary_exponentiation; mod binomial_coefficient; +mod catalan_numbers; mod ceil; mod chinese_remainder_theorem; mod collatz_sequence; @@ -52,6 +55,7 @@ mod signum; mod simpson_integration; mod sine; mod softmax; +mod sprague_grundy_theorem; mod square_pyramidal_numbers; mod square_root; mod sum_of_digits; @@ -63,12 +67,15 @@ mod zellers_congruence_algorithm; pub use self::abs::abs; pub use self::aliquot_sum::aliquot_sum; pub use self::amicable_numbers::amicable_pairs_under_n; +pub use self::area_of_polygon::area_of_polygon; +pub use self::area_under_curve::area_under_curve; pub use self::armstrong_number::is_armstrong_number; pub use self::average::{mean, median, mode}; pub use self::baby_step_giant_step::baby_step_giant_step; pub use self::bell_numbers::bell_number; pub use self::binary_exponentiation::binary_exponentiation; pub use self::binomial_coefficient::binom; +pub use self::catalan_numbers::init_catalan; pub use self::ceil::ceil; pub use self::chinese_remainder_theorem::chinese_remainder_theorem; pub use self::collatz_sequence::sequence; @@ -120,6 +127,7 @@ pub use self::signum::signum; pub use self::simpson_integration::simpson_integration; pub use self::sine::sine; pub use self::softmax::softmax; +pub use self::sprague_grundy_theorem::calculate_grundy_number; pub use self::square_pyramidal_numbers::square_pyramidal_number; pub use self::square_root::{fast_inv_sqrt, square_root}; pub use self::sum_of_digits::{sum_digits_iterative, sum_digits_recursive}; diff --git a/src/math/sprague_grundy_theorem.rs b/src/math/sprague_grundy_theorem.rs index e5cdcf854ff..4006d047ba6 100644 --- a/src/math/sprague_grundy_theorem.rs +++ b/src/math/sprague_grundy_theorem.rs @@ -13,7 +13,7 @@ * Author : [Gyandeep](https://github.com/Gyan172004) */ - pub fn calculate_grundy_number( +pub fn calculate_grundy_number( position: i64, grundy_numbers: &mut [i64], possible_moves: &[i64], @@ -53,7 +53,7 @@ // Store the calculated Grundy number and return it. grundy_numbers[position as usize] = mex; - return mex; + mex } #[cfg(test)] diff --git a/src/searching/mod.rs b/src/searching/mod.rs index adc62ba713c..94f65988195 100644 --- a/src/searching/mod.rs +++ b/src/searching/mod.rs @@ -7,6 +7,7 @@ mod jump_search; mod kth_smallest; mod kth_smallest_heap; mod linear_search; +mod moore_voting; mod quick_select; mod saddleback_search; mod ternary_search; @@ -23,6 +24,7 @@ pub use self::jump_search::jump_search; pub use self::kth_smallest::kth_smallest; pub use self::kth_smallest_heap::kth_smallest_heap; pub use self::linear_search::linear_search; +pub use self::moore_voting::moore_voting; pub use self::quick_select::quick_select; pub use self::saddleback_search::saddleback_search; pub use self::ternary_search::ternary_search; diff --git a/src/searching/moore_voting.rs b/src/searching/moore_voting.rs index bc0185cc60d..f5e8e61bd26 100644 --- a/src/searching/moore_voting.rs +++ b/src/searching/moore_voting.rs @@ -36,9 +36,9 @@ Now, this ele should be the majority element if there's any To check, a quick O(n) loop is run to check if the count of ele is >(n/2), n being the length of the array - + -1 is returned when no such element is found. - + */ pub fn moore_voting(arr: &Vec) -> i32 { @@ -46,18 +46,16 @@ pub fn moore_voting(arr: &Vec) -> i32 { let mut cnt = 0; // initializing cnt let mut ele = 0; // initializing ele - for i in 0..n { + arr.iter().for_each(|&item| { if cnt == 0 { cnt = 1; - ele = arr[i]; - } - else if arr[i] == ele { + ele = item; + } else if item == ele { cnt += 1; - } - else { + } else { cnt -= 1; } - } + }); let cnt_check = arr.iter().filter(|&&x| x == ele).count(); @@ -74,12 +72,9 @@ mod tests { #[test] fn test_moore_voting() { - let arr1: Vec = vec![9, 1, 8, 1, 1]; - assert!(moore_voting(arr1),1); - let arr2: Vec = vec![1,2,3,4]; - assert!(moore_voting(arr2),-1); - + assert!(moore_voting(&arr1) == 1); + let arr2: Vec = vec![1, 2, 3, 4]; + assert!(moore_voting(&arr2) == -1); } - } diff --git a/src/sorting/intro_sort.rs b/src/sorting/intro_sort.rs index 5791754ab3d..d6b31c17a02 100755 --- a/src/sorting/intro_sort.rs +++ b/src/sorting/intro_sort.rs @@ -45,7 +45,7 @@ fn heap_sort(arr: &mut [T]) { } } -fn intro_sort(arr: &mut [T]) { +pub fn intro_sort(arr: &mut [T]) { let len = arr.len(); let max_depth = (2.0 * len as f64).log2() as usize + 1; diff --git a/src/sorting/mod.rs b/src/sorting/mod.rs index 35abcb14f63..a8ae4f58717 100644 --- a/src/sorting/mod.rs +++ b/src/sorting/mod.rs @@ -13,6 +13,7 @@ mod exchange_sort; mod gnome_sort; mod heap_sort; mod insertion_sort; +mod intro_sort; mod merge_sort; mod odd_even_sort; mod pancake_sort; @@ -28,7 +29,9 @@ mod sleep_sort; mod sort_utils; mod stooge_sort; mod tim_sort; +mod tree_sort; mod wave_sort; +mod wiggle_sort; pub use self::bead_sort::bead_sort; pub use self::binary_insertion_sort::binary_insertion_sort; @@ -46,6 +49,7 @@ pub use self::exchange_sort::exchange_sort; pub use self::gnome_sort::gnome_sort; pub use self::heap_sort::heap_sort; pub use self::insertion_sort::insertion_sort; +pub use self::intro_sort::intro_sort; pub use self::merge_sort::bottom_up_merge_sort; pub use self::merge_sort::top_down_merge_sort; pub use self::odd_even_sort::odd_even_sort; @@ -60,7 +64,9 @@ pub use self::shell_sort::shell_sort; pub use self::sleep_sort::sleep_sort; pub use self::stooge_sort::stooge_sort; pub use self::tim_sort::tim_sort; +pub use self::tree_sort::tree_sort; pub use self::wave_sort::wave_sort; +pub use self::wiggle_sort::wiggle_sort; #[cfg(test)] use std::cmp; diff --git a/src/sorting/tree_sort.rs b/src/sorting/tree_sort.rs index ebcc7104dc6..8cf20e364ab 100644 --- a/src/sorting/tree_sort.rs +++ b/src/sorting/tree_sort.rs @@ -60,7 +60,7 @@ impl BinarySearchTree { } } -fn tree_sort(arr: &mut Vec) { +pub fn tree_sort(arr: &mut Vec) { let mut tree = BinarySearchTree::new(); for elem in arr.iter().cloned() { diff --git a/src/sorting/wiggle_sort.rs b/src/sorting/wiggle_sort.rs index 4911c145b57..0a66df7745c 100644 --- a/src/sorting/wiggle_sort.rs +++ b/src/sorting/wiggle_sort.rs @@ -5,7 +5,7 @@ //if input numbers = [3, 5, 2, 1, 6, 4] //one possible Wiggle Sorted answer is [3, 5, 1, 6, 2, 4]. -pub fn wiggle_sort(nums: Vec) -> Vec { +pub fn wiggle_sort(nums: &mut Vec) -> &mut Vec { //Rust implementation of wiggle. // Example: // >>> wiggle_sort([0, 5, 3, 2, 2]) @@ -16,44 +16,65 @@ pub fn wiggle_sort(nums: Vec) -> Vec { // [-45, -2, -5] let len = nums.len(); - let mut p = nums; for i in 1..len { - let num_x = p[i - 1]; - let num_y = p[i]; + let num_x = nums[i - 1]; + let num_y = nums[i]; if (i % 2 == 1) == (num_x > num_y) { - p[i - 1] = num_y; - p[i] = num_x; + nums[i - 1] = num_y; + nums[i] = num_x; } } - return p; + nums } #[cfg(test)] mod tests { use super::*; use crate::sorting::have_same_elements; - use crate::sorting::is_sorted; + + fn is_wiggle_sorted(nums: &Vec) -> bool { + if nums.is_empty() { + return true; + } + let mut previous = nums[0]; + let mut result = true; + nums.iter().enumerate().skip(1).for_each(|(i, &item)| { + if i != 0 { + result = + result && ((i % 2 == 1 && previous < item) || (i % 2 == 0 && previous > item)); + } + + previous = item; + }); + result + } + #[test] fn wingle_elements() { let arr = vec![3, 5, 2, 1, 6, 4]; - let cloned = arr.clone(); - let res = wiggle_sort(cloned); - assert!(is_sorted(&res) && have_same_elements(&res, &cloned)); + let mut cloned = arr.clone(); + let res = wiggle_sort(&mut cloned); + assert!(is_wiggle_sorted(res)); + assert!(have_same_elements(res, &arr)); } #[test] fn odd_number_of_elements() { let arr = vec![4, 1, 3, 5, 2]; - let cloned = arr.clone(); - let res = wiggle_sort(cloned); - assert!(is_sorted(&res) && have_same_elements(&res, &cloned)); + let mut cloned = arr.clone(); + let res = wiggle_sort(&mut cloned); + assert!(is_wiggle_sorted(res)); + assert!(have_same_elements(res, &arr)); } #[test] fn repeated_elements() { let arr = vec![5, 5, 5, 5]; - let cloned = arr.clone(); - let res = wiggle_sort(cloned); - assert!(is_sorted(&res) && have_same_elements(&res, &cloned)); + let mut cloned = arr.clone(); + let res = wiggle_sort(&mut cloned); + + // Negative test, can't be wiggle sorted + assert!(!is_wiggle_sorted(res)); + assert!(have_same_elements(res, &arr)); } }