Skip to content

Commit

Permalink
selection sort
Browse files Browse the repository at this point in the history
  • Loading branch information
2A5F committed Nov 21, 2023
1 parent 14e3de8 commit 611512b
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 1 deletion.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Provides many useful tools related to tuples
- Shorthand Macro
- Call
- Apply
- Sort

## Examples

Expand Down Expand Up @@ -245,3 +246,13 @@ Provides many useful tools related to tuples
let r = foo.apply_tuple(a);
assert_eq!(r, 6)
```
- sort
currently implemented

- selection sort

```rust
let mut a = (6, 2, 6, 8, 0, 5);
a.sort_selection();
assert_eq!(a, (0, 2, 5, 6, 6, 8))
```
4 changes: 3 additions & 1 deletion tuples/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ license = "MIT"
name = "tuples"
readme = "../README.md"
repository = "https://github.com/libsugar/tuplers"
version = "1.13.0"
version = "1.14.0"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

Expand All @@ -35,10 +35,12 @@ default = [
"re-exports",
"capt",
"tuple_get",
"sort",
]
flatten = []
re-exports = []
shorthand = []
sort = ["tuple_meta", "tuple_get"]
split = ["split_parts", "split_by", "split_to_tuple_by", "split_at", "split_to_tuple_at"]
split_at = []
split_by = []
Expand Down
5 changes: 5 additions & 0 deletions tuples/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,3 +195,8 @@ pub use capt::*;
pub mod tuple_get;
#[cfg(all(feature = "tuple_get", feature = "re-exports"))]
pub use tuple_get::*;

#[cfg(all(feature = "sort", feature = "tuple_meta", feature = "tuple_get"))]
pub mod sort;
#[cfg(all(feature = "sort", feature = "tuple_meta", feature = "tuple_get", feature = "re-exports"))]
pub use sort::*;
108 changes: 108 additions & 0 deletions tuples/src/sort.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
//! Sort tuples

use crate::{TupleGetMut, TupleSame};

/// Sort tuples using selection sort
pub trait TupleSortSelection<T> {
/// Sort tuples using selection sort
///
/// It has an `O(n2)` time complexity
fn sort_selection(&mut self);
}

impl<T: PartialOrd, S: TupleSame<T> + TupleGetMut<Output = T>> TupleSortSelection<T> for S {
#[inline]
fn sort_selection(&mut self) {
if sort_base(self, T::lt) {
return;
}
selection_sort(self, T::lt)
}
}

fn sort_base<T, S: TupleSame<T> + TupleGetMut<Output = T>>(v: &mut S, mut is_less: impl FnMut(&T, &T) -> bool) -> bool {
if core::mem::size_of::<T>() == 0 {
return true;
}

let len = v.arity();
if len <= 1 {
return true;
}
if len == 2 {
let this = v as *mut S;
let a = unsafe { (&mut *this).get_mut(0) };
let b = unsafe { (&mut *this).get_mut(1) };

if is_less(a, b) {
return true;
} else if is_less(b, a) {
core::mem::swap(a, b);
return true;
} else {
return true;
}
}

false
}

fn selection_sort<T, S: TupleSame<T> + TupleGetMut<Output = T>>(v: &mut S, mut is_less: impl FnMut(&T, &T) -> bool) {
let len = v.arity();
for i in 0..(len - 1) {
let mut min_index = i;

for j in (i + 1)..len {
if is_less(v.get(j), v.get(min_index)) {
min_index = j;
}
}

if min_index != i {
let this = v as *mut S;
let a = unsafe { (&mut *this).get_mut(i) };
let b = unsafe { (&mut *this).get_mut(min_index) };
core::mem::swap(a, b);
}
}
}

#[cfg(test)]
mod test_selection_sort {
use super::*;

#[test]
fn test1() {
let mut a = (6, 2, 6, 8, 0, 5);
a.sort_selection();
assert_eq!(a, (0, 2, 5, 6, 6, 8))
}

#[test]
fn test2() {
let mut a = (1, 2, 3, 4, 5, 6);
a.sort_selection();
assert_eq!(a, (1, 2, 3, 4, 5, 6))
}

#[test]
fn test3() {
let mut a = (2, 1);
a.sort_selection();
assert_eq!(a, (1, 2))
}

#[test]
fn test4() {
let mut a = (1, 2);
a.sort_selection();
assert_eq!(a, (1, 2))
}

#[test]
fn test5() {
let mut a = (1.5, 7.1, 3.0, 9.9, 0.3, 0.125, 0.1 + 0.2);
a.sort_selection();
assert_eq!(a, (0.125, 0.3, 0.1 + 0.2, 1.5, 3.0, 7.1, 9.9))
}
}

0 comments on commit 611512b

Please sign in to comment.