Skip to content

Commit 1d70aff

Browse files
committed
Updated pancake sort, started to add generic bitonic sort
1 parent cd6d651 commit 1d70aff

7 files changed

+238
-7
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "sorting_rs"
3-
version = "1.2.7"
3+
version = "1.2.8"
44
authors = ["flakusha <[email protected]>"]
55
edition = "2018"
66
repository = "https://github.com/flakusha/rust_sorting"

src/bin/leonardo_numbers.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
//! 32-, 64-, 128-bit and other systems.
55
//! This addition uses usize in case there is mainstream 64-bit system
66
//! # Usage:
7-
//! ```ignore
7+
//! ```text
88
//! cargo run leonardo_numbers
99
//! ```
1010
use std::io;

src/bin/powers_of_two.rs

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//! Additional private binary to print Leonardo and Fibonnaci numbers.
2+
//! Leonardo numbers are used in smoothsort algorithm as constant.
3+
//! This one can be useful in case you need to modify algorithm to use with
4+
//! 32-, 64-, 128-bit and other systems.
5+
//! This addition uses usize in case there is mainstream 64-bit system
6+
//! # Usage:
7+
//! ```text
8+
//! cargo run leonardo_numbers
9+
//! ```
10+
use std::io;
11+
12+
fn main() {
13+
let mut input = String::new();
14+
io::stdin().read_line(&mut input).expect("Failed to read value");
15+
input = input.to_string().trim().to_string();
16+
match input.parse::<usize>() {
17+
Ok(input) => {calculate_powers_of_two(input)},
18+
_ => {println!("Input is not a number!"); main();}
19+
}
20+
}
21+
22+
fn calculate_powers_of_two(input: usize) {
23+
let mut powers = Vec::<usize>::with_capacity(input);
24+
for i in 1..input + 1 {
25+
powers.push(2usize.pow(i as u32));
26+
}
27+
println!("{:?}", powers);
28+
}

src/bitonic_sort.py

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
from typing import Sequence, List
2+
3+
def bitonic_sort(up: bool, x: Sequence[int]) -> List[int]:
4+
"""Bitonic sort.
5+
6+
Args:
7+
up: ascending if ''up'' is true, and decreasing otherwise.
8+
x: A sequence of integers.
9+
10+
Returns:
11+
Sorted sequence of integers.
12+
"""
13+
if len(x) <= 1:
14+
return x
15+
else:
16+
first = bitonic_sort(True, x[:len(x) // 2])
17+
second = bitonic_sort(False, x[len(x) // 2:])
18+
return bitonic_merge(up, first + second)
19+
20+
def bitonic_merge(up: bool, x) -> List[int]:
21+
# Assume input x is bitonic, and sorted list is returned
22+
if len(x) == 1:
23+
return x
24+
else:
25+
bitonic_compare(up, x)
26+
first = bitonic_merge(up, x[:len(x) // 2])
27+
second = bitonic_merge(up, x[len(x) // 2:])
28+
return first + second
29+
30+
def bitonic_compare(up: bool, x) -> None:
31+
dist = len(x) // 2
32+
for i in range(dist):
33+
if (x[i] > x[i + dist]) == up:
34+
x[i], x[i + dist] = x[i + dist], x[i] # Swap
35+
36+
array = [10, 20, 11, 24, 15]
37+
array = bitonic_sort(True, array)
38+
print(array)

src/bitonic_sort.rs

+165
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
/// Sorts a slice in-place using
2+
/// [Bitonic sort](https://en.wikipedia.org/wiki/Bitonic_sorter).
3+
/// All kinds of slices can be sorted as long as they implement
4+
/// [`PartialOrd`](https://doc.rust-lang.org/std/cmp/trait.PartialOrd.html).
5+
///
6+
/// Bitonic sort is one of the fastest sorting networks. Sorting network has the
7+
/// sequence of comparisons that are not data-dependent.
8+
///
9+
/// # Examples
10+
/// ```rust
11+
/// let mut vec = vec![5,3,2,4];
12+
/// sorting_rs::bitonic_sort(&mut vec);
13+
/// assert_eq!(vec, &[2,3,4,5]);
14+
/// ```
15+
/// ```rust
16+
/// let mut strings = vec!["rustc", "cargo", "rustup"];
17+
/// sorting_rs::bitonic_sort(&mut strings);
18+
/// assert_eq!(strings, &["cargo", "rustc", "rustup"]);
19+
/// ```
20+
// use std::fmt::Debug;
21+
22+
pub fn bitonic_sort<T: PartialOrd + Max<T>>(input: &mut [T]) {
23+
if input.len() < 2 {return;}
24+
25+
let in_len = input.len();
26+
// Convert to vec of options
27+
// let mut input_m: Vec<Option<&T>> = input.into_iter().map(Some).collect();
28+
// Check if input array has length of power of 2 and add None to fill it up
29+
let mut add_len = 0;
30+
println!("{}", add_len);
31+
32+
for (i, num) in POWERS_OF_TWO.into_iter().enumerate() {
33+
if in_len == *num {add_len = 0;}
34+
if i > 0 {
35+
if in_len < *num {if in_len > POWERS_OF_TWO[i - 1] {
36+
add_len = num - in_len;}
37+
}
38+
}
39+
}
40+
41+
if add_len > 0 {input.append(vec![T::MAX; add_len]);}
42+
43+
sort(&mut input, true);
44+
45+
}
46+
47+
48+
// pub fn sort<T: PartialOrd>(input: &mut [T], mode: bool) {
49+
// if input.len() > 1 {
50+
// let mid_point = input.len() / 2;
51+
// sort(&mut input[..mid_point], true);
52+
// sort(&mut input[mid_point..], false);
53+
// sub_sort(input, mode);
54+
// }
55+
// }
56+
// fn sub_sort<T: PartialOrd>(input: &mut [T], mode: bool) {
57+
// if input.len() > 1 {
58+
// compare_and_swap(input, mode);
59+
// let mid_point = input.len() / 2;
60+
// sub_sort(&mut input[..mid_point], mode);
61+
// sub_sort(&mut input[mid_point..], mode);
62+
// }
63+
// }
64+
// fn compare_and_swap<T: PartialOrd>(input: &mut [T], mode: bool) {
65+
// let mid_point = input.len() / 2;
66+
// for i in 0..mid_point {
67+
// if input[i].is_none() || input[i + 1].is_none() {break;}
68+
// else if (input[i] > input[mid_point + i]) == mode {
69+
// input.swap(i, mid_point + i);
70+
// }
71+
// }
72+
// }
73+
74+
// fn bit_comp<T: PartialOrd>(input: &mut Vec<T>, mode: bool) {
75+
// let d = input.len() / 2;
76+
// for i in 0..d {
77+
// if (input[i] > input[i + d]) == mode {
78+
// input.swap(i, i + d);
79+
// }
80+
// }
81+
// }
82+
83+
/// usize for 64 bit is limited with 63 numbers
84+
const POWERS_OF_TWO: [usize; 63] = [2, 4, 8, 16, 32, 64, 128, 256, 512, 1024,
85+
2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576,
86+
2097152, 4194304, 8388608, 16777216, 33554432, 67108864, 134217728, 268435456,
87+
536870912, 1073741824, 2147483648, 4294967296, 8589934592, 17179869184,
88+
34359738368, 68719476736, 137438953472, 274877906944, 549755813888,
89+
1099511627776, 2199023255552, 4398046511104, 8796093022208, 17592186044416,
90+
35184372088832, 70368744177664, 140737488355328, 281474976710656,
91+
562949953421312, 1125899906842624, 2251799813685248, 4503599627370496,
92+
9007199254740992, 18014398509481984, 36028797018963968, 72057594037927936,
93+
144115188075855872, 288230376151711744, 576460752303423488, 1152921504606846976,
94+
2305843009213693952, 4611686018427387904, 9223372036854775808];
95+
96+
/// Implemented Max values for generics to use in the code
97+
macro_rules! impl_max {
98+
($($t:ty)*) => ($(
99+
impl Max for $t {
100+
#[inline]
101+
fn get_max(&self) -> Self {*self::MAX}
102+
}
103+
)*)
104+
}
105+
pub trait Max<T: PartialOrd> {fn get_max(&self) -> Self;}
106+
// impl Max<T> for T {fn get_max(&self) -> T {T::MAX}}
107+
// impl Max<u8> for u8 {fn get_max(&self) -> u8 {u8::MAX}}
108+
impl_max! {
109+
bool char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64
110+
}
111+
112+
113+
// fn bit_sort<T: PartialOrd>(input: &mut Vec<T>, mode: bool) {
114+
// if input.len() < 2 {return;}
115+
116+
// let mut left: Vec<T> = input.drain(..input.len() / 2).collect();
117+
// bit_sort(&mut left, true);
118+
// bit_sort(input, false);
119+
// left.append(input);
120+
// bit_merge(&mut left, mode);
121+
// std::mem::swap(input, &mut left);
122+
// }
123+
124+
// fn bit_merge<T: PartialOrd>(input: &mut Vec<T>, mode) {
125+
// if input.len() == 1 {return;}
126+
// else {
127+
// bit_comp(input, mode);
128+
// let mut left: Vec<T> = input.drain(..input.len() / 2).collect();
129+
// bit_merge(mode, &mut left);
130+
// bit_merge(mode, input);
131+
// left.append(input);
132+
// std::mem::swap(input, &mut left);
133+
// }
134+
// }
135+
136+
#[cfg(test)]
137+
mod tests {
138+
use super::*;
139+
140+
#[test]
141+
fn test_bitonic() {
142+
let mut vector_in = vec![10, 20, 11, 24, 15];
143+
bitonic_sort(&mut vector_in);
144+
debug_assert_eq!(vector_in, vec![10, 11, 15, 20, 24]);
145+
}
146+
#[test]
147+
fn test_bitonic_empty() {
148+
let mut vector_in:Vec<u8> = vec![];
149+
bitonic_sort(&mut vector_in);
150+
debug_assert_eq!(vector_in, vec![]);
151+
}
152+
#[test]
153+
fn test_bitonic_len1() {
154+
let mut vector_in = vec![1];
155+
bitonic_sort(&mut vector_in);
156+
debug_assert_eq!(vector_in, vec![1]);
157+
}
158+
#[test]
159+
fn test_u8_max() {
160+
161+
let mut input = 12;
162+
input = input.get_max();
163+
debug_assert_eq!(input, u8::MAX);
164+
}
165+
}

src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
//! | Stooge | it's a bit faster than slow sort | `n`<sup>`2.7095`</sup> | | `n` |
2929
3030
pub mod bingo_sort;
31+
// pub mod bitonic_sort;
3132
pub mod bubble_sort;
3233
pub mod cocktail_sort;
3334
pub mod comb_sort;
@@ -48,6 +49,7 @@ pub mod smooth_sort;
4849
pub mod stooge_sort;
4950

5051
pub use self::bingo_sort::bingo_sort;
52+
// pub use self::bitonic_sort::bitonic_sort;
5153
pub use self::bubble_sort::bubble_sort;
5254
pub use self::cocktail_sort::cocktail_sort;
5355
pub use self::comb_sort::comb_sort;

src/pancake_sort.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
/// assert_eq!(strings, &["cargo", "rustc", "rustup"]);
2020
/// ```
2121
22-
pub fn pancake_sort<T: PartialOrd + Copy>(input: &mut Vec<T>) {
22+
pub fn pancake_sort<T: PartialOrd + Copy>(input: &mut [T]) {
2323
if input.len() < 2 {return;}
2424

2525
let in_len = input.len() - 1;
@@ -45,10 +45,8 @@ fn largest_pancake<T: PartialOrd + Copy>(input: &[T], index: usize)
4545
largest
4646
}
4747

48-
fn flip<T: PartialOrd + Copy>(input: &mut Vec<T>, index: usize) {
49-
let mut pile:Vec<T> = input.drain(0..=index).rev().collect();
50-
pile.append(input);
51-
std::mem::swap(input, &mut pile);
48+
fn flip<T: PartialOrd + Copy>(input: &mut [T], index: usize) {
49+
input[..=index].reverse();
5250
}
5351

5452

0 commit comments

Comments
 (0)