From d0de63ca35c408526a2b97ac5926dd9e6549cf11 Mon Sep 17 00:00:00 2001 From: jacekpoz Date: Mon, 6 May 2024 22:55:10 +0200 Subject: [PATCH] general cleanup --- lab2/zad1/hybridsort/src/main.rs | 11 +-- lab2/zad1/insertionsort/src/main.rs | 11 +-- lab2/zad1/quicksort/src/main.rs | 11 +-- lab2/zad3/src/main.rs | 7 -- lab2/zad3/src/merge.rs | 34 ------- lab2/zad3/src/mergesort.rs | 16 ---- lab2/zad3/src/mysort.rs | 70 --------------- lab3/gen_asc/Cargo.lock | 82 ----------------- lab3/gen_asc/Cargo.toml | 7 -- lab3/gen_asc/src/main.rs | 19 ---- lab3/gen_desc/Cargo.toml | 7 -- lab3/gen_desc/src/main.rs | 19 ---- lab3/gen_rand/Cargo.lock | 8 +- lab3/gen_rand/Cargo.toml | 2 +- lab3/gen_rand/src/main.rs | 15 +++- lab3/libgen/Cargo.lock | 75 ---------------- lab3/libgen/src/lib.rs | 36 -------- lab3/libsort/src/lib.rs | 99 --------------------- lab3/libsort/src/main.rs | 20 ----- lab3/{libgen => rand_select}/Cargo.toml | 3 +- lab3/rand_select/src/main.rs | 3 + lab3/{gen_desc => select}/Cargo.lock | 30 ++++--- lab3/select/Cargo.toml | 8 ++ lab3/select/src/main.rs | 58 ++++++++++++ {lab3/libsort => libselect}/Cargo.lock | 7 +- {lab3/libsort => libselect}/Cargo.toml | 3 +- libselect/src/lib.rs | 19 ++++ libselect/src/normal_select.rs | 112 ++++++++++++++++++++++++ libselect/src/randomized_select.rs | 85 ++++++++++++++++++ libsort/src/hybrid_sort.rs | 6 ++ libsort/src/my_sort.rs | 5 ++ libsort/src/quick_sort.rs | 2 +- 32 files changed, 354 insertions(+), 536 deletions(-) delete mode 100644 lab2/zad3/src/merge.rs delete mode 100644 lab2/zad3/src/mergesort.rs delete mode 100644 lab2/zad3/src/mysort.rs delete mode 100644 lab3/gen_asc/Cargo.lock delete mode 100644 lab3/gen_asc/Cargo.toml delete mode 100644 lab3/gen_asc/src/main.rs delete mode 100644 lab3/gen_desc/Cargo.toml delete mode 100644 lab3/gen_desc/src/main.rs delete mode 100644 lab3/libgen/Cargo.lock delete mode 100644 lab3/libgen/src/lib.rs delete mode 100644 lab3/libsort/src/lib.rs delete mode 100644 lab3/libsort/src/main.rs rename lab3/{libgen => rand_select}/Cargo.toml (66%) create mode 100644 lab3/rand_select/src/main.rs rename lab3/{gen_desc => select}/Cargo.lock (84%) create mode 100644 lab3/select/Cargo.toml create mode 100644 lab3/select/src/main.rs rename {lab3/libsort => libselect}/Cargo.lock (96%) rename {lab3/libsort => libselect}/Cargo.toml (58%) create mode 100644 libselect/src/lib.rs create mode 100644 libselect/src/normal_select.rs create mode 100644 libselect/src/randomized_select.rs diff --git a/lab2/zad1/hybridsort/src/main.rs b/lab2/zad1/hybridsort/src/main.rs index 2ab4230..2b7efdf 100644 --- a/lab2/zad1/hybridsort/src/main.rs +++ b/lab2/zad1/hybridsort/src/main.rs @@ -1,6 +1,6 @@ use std::io; -use libsort::{hybrid_sort::HybridSort, is_sorted, print_list, Sort}; +use libsort::{hybrid_sort::HybridSort, is_sorted, Sort}; fn main() -> io::Result<()> { let mut buffer = String::new(); @@ -28,8 +28,7 @@ fn main() -> io::Result<()> { let print = input_list.len() < 40; if print { - print!("input: "); - print_list(&input_list); + println!("input: {:?}", input_list); println!(); } @@ -39,11 +38,9 @@ fn main() -> io::Result<()> { if print { println!(); - print!("input: "); - print_list(&input_list); + println!("input: {:?}", input_list); println!(); - print!("output: "); - print_list(&list); + println!("output: {:?}", list); } println!("swaps: {}", hybrid.num_swap()); diff --git a/lab2/zad1/insertionsort/src/main.rs b/lab2/zad1/insertionsort/src/main.rs index 4a03e43..d547198 100644 --- a/lab2/zad1/insertionsort/src/main.rs +++ b/lab2/zad1/insertionsort/src/main.rs @@ -1,6 +1,6 @@ use std::io; -use libsort::{insertion_sort::InsertionSort, is_sorted, print_list, Sort}; +use libsort::{insertion_sort::InsertionSort, is_sorted, Sort}; fn main() -> io::Result<()> { let mut buffer = String::new(); @@ -28,8 +28,7 @@ fn main() -> io::Result<()> { let print = input_list.len() < 40; if print { - print!("input: "); - print_list(&input_list); + println!("input: {:?}", input_list); println!(); } @@ -39,11 +38,9 @@ fn main() -> io::Result<()> { if print { println!(); - print!("input: "); - print_list(&input_list); + println!("input: {:?}", input_list); println!(); - print!("output: "); - print_list(&list); + println!("output: {:?}", list); } println!("swaps: {}", insertion.num_swap()); diff --git a/lab2/zad1/quicksort/src/main.rs b/lab2/zad1/quicksort/src/main.rs index 98d7e88..dc2c382 100644 --- a/lab2/zad1/quicksort/src/main.rs +++ b/lab2/zad1/quicksort/src/main.rs @@ -1,6 +1,6 @@ use std::io; -use libsort::{is_sorted, print_list, quick_sort::QuickSort, Sort}; +use libsort::{is_sorted, quick_sort::QuickSort, Sort}; fn main() -> io::Result<()> { let mut buffer = String::new(); @@ -28,8 +28,7 @@ fn main() -> io::Result<()> { let print = input_list.len() < 40; if print { - print!("input: "); - print_list(&input_list); + println!("input: {:?}", input_list); println!(); } @@ -39,11 +38,9 @@ fn main() -> io::Result<()> { if print { println!(); - print!("input: "); - print_list(&input_list); + println!("input: {:?}", input_list); println!(); - print!("output: "); - print_list(&list); + println!("output: {:?}", list); } println!("swaps: {}", quick.num_swap()); diff --git a/lab2/zad3/src/main.rs b/lab2/zad3/src/main.rs index 4a912bb..531ef66 100644 --- a/lab2/zad3/src/main.rs +++ b/lab2/zad3/src/main.rs @@ -1,14 +1,7 @@ -mod merge; -mod mergesort; -mod mysort; - use std::{collections::HashMap, env::args, fs::{self, OpenOptions}, io::{self, Write}}; use libgen::gen_rand; use libsort::{is_sorted, merge_sort::MergeSort, my_sort::MySort, Sort}; -use mergesort::mergesort; - -use crate::mysort::mysort; fn comp_avg(results_map: &HashMap>) -> HashMap { results_map.iter() diff --git a/lab2/zad3/src/merge.rs b/lab2/zad3/src/merge.rs deleted file mode 100644 index 7bab7aa..0000000 --- a/lab2/zad3/src/merge.rs +++ /dev/null @@ -1,34 +0,0 @@ -use libsort::{compare, CompareResult::*, SortResult}; - -pub fn merge(list1: &[u64], list2: &[u64], res: &mut SortResult) -> Vec { - let mut ret = vec![]; - - let mut i = 0; - let mut j = 0; - - while i < list1.len() && j < list2.len() { - if compare(list1[i], list2[j], &mut res.comparisons) == LESS { - ret.push(list1[i]); - i = i + 1; - } else { - ret.push(list2[j]); - j = j + 1; - } - } - - if i < list1.len() { - while i < list1.len() { - ret.push(list1[i]); - i = i + 1; - } - } - - if j < list2.len() { - while j < list2.len() { - ret.push(list2[j]); - j = j + 1; - } - } - - ret -} diff --git a/lab2/zad3/src/mergesort.rs b/lab2/zad3/src/mergesort.rs deleted file mode 100644 index 5935b9e..0000000 --- a/lab2/zad3/src/mergesort.rs +++ /dev/null @@ -1,16 +0,0 @@ -use libsort::SortResult; - -use crate::merge::merge; - -pub fn mergesort(list: &[u64], res: &mut SortResult) -> Vec { - if list.len() > 1 { - let size = list.len() / 2; - let left = mergesort(&list[0..size], res); - let right = mergesort(&list[size..], res); - let merged = merge(&left, &right, res); - - return merged; - } - - list.to_vec() -} diff --git a/lab2/zad3/src/mysort.rs b/lab2/zad3/src/mysort.rs deleted file mode 100644 index 61a7093..0000000 --- a/lab2/zad3/src/mysort.rs +++ /dev/null @@ -1,70 +0,0 @@ -use libsort::{compare, CompareResult::*, SortResult}; - -use crate::merge::merge; - -fn extend_run_left(list: &[u64], mut i: usize, res: &mut SortResult) -> usize { - while i > 0 && compare(list[i - 1], list[i], &mut res.comparisons) != GREATER { - i -= 1; - } - - i -} - -fn extend_run_right(list: &[u64], mut i: usize, res: &mut SortResult) -> usize { - while i < list.len() - 1 && compare(list[i], list[i + 1], &mut res.comparisons) != GREATER { - i += 1; - } - - i -} - -fn _mysort(list: &mut [u64], low: usize, high: usize, e: usize, s: usize) -> SortResult { - let mut res = SortResult::default(); - - if e == high || s == low { - return res; - } - let mid = low + (high - low) / 2; - - if mid <= e { - let res1 = _mysort(list, e + 1, high, e + 1, s); - list.copy_from_slice(&merge(&list[low..=e], &list[(e + 1)..=high], &mut res)); - - res.comparisons += res1.comparisons; - res.swaps += res1.swaps; - } else if mid >= s { - let res1 = _mysort(list, low, s - 1, e, s - 1); - list.copy_from_slice(&merge(&list[low..=(s - 1)], &list[s..=high], &mut res)); - - res.comparisons += res1.comparisons; - res.swaps += res1.swaps; - } else { - let i = extend_run_left(list, low, &mut res); - let j = extend_run_right(list, high, &mut res); - if i == low && j == high { - return res; - } - - if mid - i < j - mid { - let res1 = _mysort(list, low, i - 1, e, i - 1); - let res2 = _mysort(list, i, high, j, s); - list.copy_from_slice(&merge(&list[low..=(i - 1)], &list[i..=high], &mut res)); - - res.comparisons += res1.comparisons + res2.comparisons; - res.swaps += res1.swaps + res2.swaps; - } else { - let res1 = _mysort(list, low, j, e, i); - let res2 = _mysort(list, j + 1, high, j + 1, s); - list.copy_from_slice(&merge(&list[low..=j], &list[(j + 1)..=high], &mut res)); - - res.comparisons += res1.comparisons + res2.comparisons; - res.swaps += res1.swaps + res2.swaps; - } - } - - res -} - -pub fn mysort(list: &mut [u64]) -> SortResult { - _mysort(list, 0, list.len() - 1, 0, list.len() - 1) -} diff --git a/lab3/gen_asc/Cargo.lock b/lab3/gen_asc/Cargo.lock deleted file mode 100644 index da99ecd..0000000 --- a/lab3/gen_asc/Cargo.lock +++ /dev/null @@ -1,82 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "gen_asc" -version = "0.1.0" -dependencies = [ - "libgen", -] - -[[package]] -name = "getrandom" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "libc" -version = "0.2.153" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" - -[[package]] -name = "libgen" -version = "0.1.0" -dependencies = [ - "rand", -] - -[[package]] -name = "ppv-lite86" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" diff --git a/lab3/gen_asc/Cargo.toml b/lab3/gen_asc/Cargo.toml deleted file mode 100644 index 950482e..0000000 --- a/lab3/gen_asc/Cargo.toml +++ /dev/null @@ -1,7 +0,0 @@ -[package] -name = "gen_asc" -version = "0.1.0" -edition = "2021" - -[dependencies] -libgen = { path = "../libgen" } diff --git a/lab3/gen_asc/src/main.rs b/lab3/gen_asc/src/main.rs deleted file mode 100644 index 62fdc88..0000000 --- a/lab3/gen_asc/src/main.rs +++ /dev/null @@ -1,19 +0,0 @@ -use std::{env::args, io}; - -use libgen::gen_asc; - -fn main() -> io::Result<()> { - - let amount = args().nth(1) - .expect(format!("usage: {} ", args().nth(0).unwrap()).as_str()) - .parse::() - .expect("amount must be u64"); - - println!("{}", amount); - - gen_asc(amount) - .iter() - .for_each(|x| println!("{}", x)); - - Ok(()) -} diff --git a/lab3/gen_desc/Cargo.toml b/lab3/gen_desc/Cargo.toml deleted file mode 100644 index d46effa..0000000 --- a/lab3/gen_desc/Cargo.toml +++ /dev/null @@ -1,7 +0,0 @@ -[package] -name = "gen_desc" -version = "0.1.0" -edition = "2021" - -[dependencies] -libgen = { path = "../libgen" } diff --git a/lab3/gen_desc/src/main.rs b/lab3/gen_desc/src/main.rs deleted file mode 100644 index ee96448..0000000 --- a/lab3/gen_desc/src/main.rs +++ /dev/null @@ -1,19 +0,0 @@ -use std::{env::args, io}; - -use libgen::gen_desc; - -fn main() -> io::Result<()> { - - let amount = args().nth(1) - .expect(format!("usage: {} ", args().nth(0).unwrap()).as_str()) - .parse::() - .expect("amount must be u64"); - - println!("{}", amount); - - gen_desc(amount) - .iter() - .for_each(|x| println!("{}", x)); - - Ok(()) -} diff --git a/lab3/gen_rand/Cargo.lock b/lab3/gen_rand/Cargo.lock index 02aac01..82b8dd8 100644 --- a/lab3/gen_rand/Cargo.lock +++ b/lab3/gen_rand/Cargo.lock @@ -17,9 +17,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", @@ -28,9 +28,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.153" +version = "0.2.154" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" [[package]] name = "libgen" diff --git a/lab3/gen_rand/Cargo.toml b/lab3/gen_rand/Cargo.toml index 8d566a2..31058c9 100644 --- a/lab3/gen_rand/Cargo.toml +++ b/lab3/gen_rand/Cargo.toml @@ -4,4 +4,4 @@ version = "0.1.0" edition = "2021" [dependencies] -libgen = { path = "../libgen" } +libgen = { path = "../../libgen" } diff --git a/lab3/gen_rand/src/main.rs b/lab3/gen_rand/src/main.rs index d36e463..02a8cb0 100644 --- a/lab3/gen_rand/src/main.rs +++ b/lab3/gen_rand/src/main.rs @@ -1,15 +1,26 @@ -use std::{env::args, io}; +use std::{env::args, io, process::exit}; use libgen::gen_rand; fn main() -> io::Result<()> { let amount = args().nth(1) - .expect(format!("usage: {} ", args().nth(0).unwrap()).as_str()) + .expect(format!("usage: {} ", args().nth(0).unwrap()).as_str()) .parse::() .expect("amount must be u64"); + let order_statistic = args().nth(2) + .expect(format!("usage: {} ", args().nth(0).unwrap()).as_str()) + .parse::() + .expect("order statistic must be u64"); + + if !(1..=amount).contains(&order_statistic) { + eprintln!("order statistic must be in range [1..{}]", amount); + exit(1); + } + println!("{}", amount); + println!("{}", order_statistic); gen_rand(amount) .iter() diff --git a/lab3/libgen/Cargo.lock b/lab3/libgen/Cargo.lock deleted file mode 100644 index 1da0f1b..0000000 --- a/lab3/libgen/Cargo.lock +++ /dev/null @@ -1,75 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "getrandom" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "libc" -version = "0.2.153" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" - -[[package]] -name = "libgen" -version = "0.1.0" -dependencies = [ - "rand", -] - -[[package]] -name = "ppv-lite86" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" diff --git a/lab3/libgen/src/lib.rs b/lab3/libgen/src/lib.rs deleted file mode 100644 index cd3b7df..0000000 --- a/lab3/libgen/src/lib.rs +++ /dev/null @@ -1,36 +0,0 @@ -use rand::Rng; - -pub fn gen_rand(amount: u64) -> Vec { - (1..=amount) - .map(|_| rand::thread_rng().gen_range(0..(2 * amount))) - .collect() -} - -pub fn gen_desc(amount: u64) -> Vec { - let mut ret = vec![]; - - let mut last = rand::thread_rng().gen_range((amount)..(2 * amount)); - ret.push(last); - - for i in 1..amount { - let current = rand::thread_rng().gen_range((amount - i)..(last)); - ret.push(current); - last = current; - } - - ret -} - -pub fn gen_asc(amount: u64) -> Vec { - let mut ret = vec![]; - - let mut last = -1; - - for i in 1..=amount { - let current = rand::thread_rng().gen_range((last + 1)..=(2 * amount - (amount - i)) as i64); - ret.push(current as u64); - last = current; - } - - ret -} diff --git a/lab3/libsort/src/lib.rs b/lab3/libsort/src/lib.rs deleted file mode 100644 index 962b3b4..0000000 --- a/lab3/libsort/src/lib.rs +++ /dev/null @@ -1,99 +0,0 @@ -use rand::{thread_rng, Rng}; - -pub fn insertion_sort_mut(list: &mut [u64]) { - for i in 1..list.len() { - let mut j = i as usize; - - while j > 0 && list[j - 1] > list[j] { - list.swap(j - 1, j); - j -= 1; - } - } -} - -pub fn insertion_sort(list: &[u64]) -> Vec { - let mut clone = Vec::from(list); - insertion_sort_mut(&mut clone); - clone -} - -fn partition(arr: &mut [u64], lo: usize, hi: usize, pivot: u64) -> usize { - let mut pivot_index = lo; - for i in lo..=hi { - if arr[i] == pivot { - pivot_index = i; - break; - } - } - - if pivot_index != lo { - arr.swap(pivot_index, lo); - pivot_index = lo; - } - let mut j = lo; - for i in (lo + 1)..=hi { - if arr[pivot_index] > arr[i] { - j += 1; - arr.swap(j, i); - } - } - arr.swap(j, lo); - j -} - -pub fn rand_partition(arr: &mut [u64], lo: usize, hi: usize) -> usize { - let pivot = thread_rng().gen_range(lo..hi); - partition(arr, lo, hi, arr[pivot]) -} - -fn _rand_select(arr: &mut [u64], lo: usize, hi: usize, k: usize) -> (usize, u64) { - if lo == hi { - return (lo, arr[lo]); - } - let r = rand_partition(arr, lo, hi); - let i = r - lo + 1; - if k == i { - return (r, arr[r]); - } else if k < i { - return _rand_select(arr, lo, r - 1, k); - } else { - return _rand_select(arr, r + 1, hi, k - i); - } -} - -pub fn rand_select(arr: &mut [u64], k: usize) -> (usize, u64) { - _rand_select(arr, 0, arr.len() - 1, k) -} - -fn _select(arr: &mut [u64], lo: usize, hi: usize, k: usize) -> (usize, u64) { - if lo == hi { - return (lo, arr[lo]); - } - - let mut medians: Vec = vec![]; - let mut chunks = arr.chunks(5) - .collect::>(); - - for chunk in chunks.iter_mut() { - let chunk = insertion_sort(chunk); - medians.push(chunk[chunk.len() / 2]); - } - - let n = hi - lo; - - let (_, pivot) = _select(&mut medians, 0, n.div_ceil(5) - 1, (n.div_ceil(5) - 1).div_ceil(2)); - let r = partition(arr, lo, hi, pivot); - let i = r - lo + 1; - - if i == k { - return (r, arr[r]); - } else if i < k { - return _select(arr, r + 1, hi, k - i); - } else { - return _select(arr, lo, r - 1, k); - } -} - -pub fn select(arr: &mut [u64], k: usize) -> (usize, u64) { - _select(arr, 0, arr.len() - 1, k) -} diff --git a/lab3/libsort/src/main.rs b/lab3/libsort/src/main.rs deleted file mode 100644 index 360e444..0000000 --- a/lab3/libsort/src/main.rs +++ /dev/null @@ -1,20 +0,0 @@ -use libsort::{select, rand_select}; - -fn main() { - let arr = [3, 28, 9, 2, 4, 42, 23, 123, 24, 12, 43, 287, 723, 61]; - print!("select: "); - for pos in 1..=arr.len() { - // println!("input: {:?}", arr); - // println!("positional statistic: {}", pos); - // println!("select: {:?}", select(&mut arr.clone(), pos).1); - // println!("rand_select: {:?}", rand_select(&mut arr.clone(), pos).1); - print!("{} ", select(&mut arr.clone(), pos).1); - } - print!("\n"); - - print!("rand_select: "); - for pos in 1..=arr.len() { - print!("{} ", rand_select(&mut arr.clone(), pos).1); - } - print!("\n"); -} diff --git a/lab3/libgen/Cargo.toml b/lab3/rand_select/Cargo.toml similarity index 66% rename from lab3/libgen/Cargo.toml rename to lab3/rand_select/Cargo.toml index b2ef245..26c3f9d 100644 --- a/lab3/libgen/Cargo.toml +++ b/lab3/rand_select/Cargo.toml @@ -1,7 +1,6 @@ [package] -name = "libgen" +name = "rand_select" version = "0.1.0" edition = "2021" [dependencies] -rand = "0.8.5" diff --git a/lab3/rand_select/src/main.rs b/lab3/rand_select/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/lab3/rand_select/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/lab3/gen_desc/Cargo.lock b/lab3/select/Cargo.lock similarity index 84% rename from lab3/gen_desc/Cargo.lock rename to lab3/select/Cargo.lock index c432d62..4650615 100644 --- a/lab3/gen_desc/Cargo.lock +++ b/lab3/select/Cargo.lock @@ -8,18 +8,11 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "gen_desc" -version = "0.1.0" -dependencies = [ - "libgen", -] - [[package]] name = "getrandom" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", @@ -28,17 +21,22 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.153" +version = "0.2.154" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" [[package]] -name = "libgen" +name = "libselect" version = "0.1.0" dependencies = [ + "libsort", "rand", ] +[[package]] +name = "libsort" +version = "0.1.0" + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -75,6 +73,14 @@ dependencies = [ "getrandom", ] +[[package]] +name = "select" +version = "0.1.0" +dependencies = [ + "libselect", + "libsort", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" diff --git a/lab3/select/Cargo.toml b/lab3/select/Cargo.toml new file mode 100644 index 0000000..54c5fef --- /dev/null +++ b/lab3/select/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "select" +version = "0.1.0" +edition = "2021" + +[dependencies] +libselect = { path = "../../libselect" } +libsort = { path = "../../libsort" } diff --git a/lab3/select/src/main.rs b/lab3/select/src/main.rs new file mode 100644 index 0000000..5d30bf1 --- /dev/null +++ b/lab3/select/src/main.rs @@ -0,0 +1,58 @@ +use std::{io, process::exit}; + +use libselect::{normal_select::NormalSelect, Select}; +use libsort::{insertion_sort::InsertionSort, quick_sort::QuickSort, Sort}; + +fn main() -> io::Result<()> { + let mut buffer = String::new(); + + let stdin = io::stdin(); + + stdin.read_line(&mut buffer)?; + + let list_len = buffer.trim().parse::().expect("array length has to be u64"); + buffer.clear(); + + stdin.read_line(&mut buffer)?; + + let order_statistic = buffer.trim().parse::().expect("order statistic has to be usize"); + buffer.clear(); + + if !(1..=list_len as usize).contains(&order_statistic) { + eprintln!("order statistic must be in range [1..{}]", list_len); + exit(1); + } + + let mut list: Vec = vec![]; + + for i in 0..list_len { + stdin.read_line(&mut buffer)?; + list.push( + buffer.trim().parse::() + .expect(format!("element {} has to be u64", i).as_str()) + ); + buffer.clear(); + } + + let input_list: Vec = list.clone(); + + let print = input_list.len() <= 50; + + let mut normal = NormalSelect::new(print); + + let result = normal.select_mut(&mut list, order_statistic); + + if print { + println!(); + println!("start state: {:?}", input_list); + println!("end state: {:?}", list); + let mut insertion = InsertionSort::new(false); + println!("sorted array: {:?}", insertion.sort(&input_list)); + println!("{} order statistic: {}", order_statistic, result); + } + + println!("swaps: {}", normal.num_swap()); + println!("comparisons: {}", normal.num_comp()); + + Ok(()) +} diff --git a/lab3/libsort/Cargo.lock b/libselect/Cargo.lock similarity index 96% rename from lab3/libsort/Cargo.lock rename to libselect/Cargo.lock index 4f69c8b..d6f1398 100644 --- a/lab3/libsort/Cargo.lock +++ b/libselect/Cargo.lock @@ -26,12 +26,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" [[package]] -name = "libsort" +name = "libselect" version = "0.1.0" dependencies = [ + "libsort", "rand", ] +[[package]] +name = "libsort" +version = "0.1.0" + [[package]] name = "ppv-lite86" version = "0.2.17" diff --git a/lab3/libsort/Cargo.toml b/libselect/Cargo.toml similarity index 58% rename from lab3/libsort/Cargo.toml rename to libselect/Cargo.toml index feeebeb..801073f 100644 --- a/lab3/libsort/Cargo.toml +++ b/libselect/Cargo.toml @@ -1,7 +1,8 @@ [package] -name = "libsort" +name = "libselect" version = "0.1.0" edition = "2021" [dependencies] rand = "0.8.5" +libsort = { path = "../libsort" } diff --git a/libselect/src/lib.rs b/libselect/src/lib.rs new file mode 100644 index 0000000..d0ec206 --- /dev/null +++ b/libselect/src/lib.rs @@ -0,0 +1,19 @@ +pub mod normal_select; +pub mod randomized_select; + +pub trait Select { + fn new(should_print: bool) -> Self; + fn select_mut(&mut self, list: &mut Vec, order_statistic: usize) -> u64; + fn select(&mut self, list: &Vec, order_statistic: usize) -> u64 { + let mut list = list.clone(); + self.select_mut(&mut list, order_statistic) + } + fn num_comp(&self) -> u64; + fn num_swap(&self) -> u64; + fn reset_state(&mut self); +} + +#[derive(PartialEq)] +pub enum CompareResult { + LESS, EQUAL, GREATER +} diff --git a/libselect/src/normal_select.rs b/libselect/src/normal_select.rs new file mode 100644 index 0000000..41eae30 --- /dev/null +++ b/libselect/src/normal_select.rs @@ -0,0 +1,112 @@ +use libsort::{insertion_sort::InsertionSort, Sort}; + +use crate::{CompareResult, Select}; + +pub struct NormalSelect { + comparisons: u64, + swaps: u64, + should_print: bool, + insertion: InsertionSort, +} + +impl NormalSelect { + fn swap(&mut self, list: &mut Vec, i: usize, j: usize) { + self.swaps += 1; + list.swap(i, j); + } + fn compare(&mut self, a: u64, b: u64) -> CompareResult { + self.comparisons += 1; + if a < b { + CompareResult::LESS + } else if a > b { + CompareResult::GREATER + } else { + CompareResult::EQUAL + } + } + + pub fn partition(&mut self, list: &mut Vec, lo: usize, hi: usize, mut pivot_index: usize) -> usize { + if pivot_index != lo { + self.swap(list, pivot_index, lo); + pivot_index = lo; + } + let mut j = lo; + for i in (lo + 1)..=hi { + use CompareResult::*; + if self.compare(list[pivot_index],list[i]) == GREATER { + j += 1; + self.swap(list, j, i); + } + } + self.swap(list, j, lo); + j + } + + fn _select(&mut self, list: &mut Vec, lo: usize, hi: usize, k: usize) -> (usize, u64) { + if lo == hi { + return (lo, list[lo]); + } + + if self.should_print { println!("list: {:?}; lo: {lo}; hi: {hi}", list); } + + let mut medians: Vec = vec![]; + let mut chunks = list.chunks(5) + .collect::>(); + + for chunk in chunks.iter_mut() { + let chunk = self.insertion.sort(&chunk.to_vec()); + medians.push(chunk[chunk.len() / 2]); + } + + if self.should_print { println!("medians: {:?}", medians); } + + self.comparisons += self.insertion.num_comp(); + self.swaps += self.insertion.num_swap(); + self.insertion.reset_state(); + + let n = hi - lo; + + let (pivot, _) = self._select(&mut medians, 0, n.div_ceil(5) - 1, (n.div_ceil(5) - 1).div_ceil(2)); + if self.should_print { println!("pivot: {pivot}"); } + let r = self.partition(list, lo, hi, pivot); + if self.should_print { println!("r: {r}"); } + let i = r - lo + 1; + + if i == k { + return (r, list[r]); + } else if i < k { + return self._select(list, r + 1, hi, k - i); + } else { + return self._select(list, lo, r - 1, k); + } + } +} + +impl Select for NormalSelect { + fn new(should_print: bool) -> Self { + Self { + comparisons: 0, + swaps: 0, + should_print, + insertion: InsertionSort::new(false), + } + } + + fn select_mut(&mut self, list: &mut Vec, order_statistic: usize) -> u64 { + self._select(list, 0, list.len() - 1, order_statistic).1 + } + + fn num_comp(&self) -> u64 { + self.comparisons + } + + fn num_swap(&self) -> u64 { + self.swaps + } + + fn reset_state(&mut self) { + self.comparisons = 0; + self.swaps = 0; + self.insertion.reset_state(); + } +} diff --git a/libselect/src/randomized_select.rs b/libselect/src/randomized_select.rs new file mode 100644 index 0000000..d1dfc4d --- /dev/null +++ b/libselect/src/randomized_select.rs @@ -0,0 +1,85 @@ +use rand::{thread_rng, Rng}; + +use crate::{normal_select::NormalSelect, CompareResult, Select}; + +pub struct RandomizedSelect { + comparisons: u64, + swaps: u64, + should_print: bool, + normal: NormalSelect, +} + +impl RandomizedSelect { + fn swap(&mut self, list: &mut Vec, i: usize, j: usize) { + self.swaps += 1; + list.swap(i, j); + } + fn compare(&mut self, a: u64, b: u64) -> CompareResult { + self.comparisons += 1; + if a < b { + CompareResult::LESS + } else if a > b { + CompareResult::GREATER + } else { + CompareResult::EQUAL + } + } + + fn rand_partition(&mut self, list: &mut Vec, lo: usize, hi: usize) -> usize { + let pivot = thread_rng().gen_range(lo..hi); + if self.should_print { println!("pivot: {pivot}"); } + self.normal.partition(list, lo, hi, pivot) + } + + fn _select(&mut self, list: &mut Vec, lo: usize, hi: usize, k: usize) -> (usize, u64) { + if lo == hi { + return (lo, list[lo]); + } + + if self.should_print { println!("list: {:?}; lo: {lo}; hi: {hi}", list); } + + let r = self.rand_partition(list, lo, hi); + if self.should_print { println!("r: {r}"); } + + self.comparisons += self.normal.num_comp(); + self.swaps += self.normal.num_swap(); + self.normal.reset_state(); + let i = r - lo + 1; + if k == i { + return (r, list[r]); + } else if k < i { + return self._select(list, lo, r - 1, k); + } else { + return self._select(list, r + 1, hi, k - i); + } + } +} + +impl Select for RandomizedSelect { + fn new(should_print: bool) -> Self { + Self { + comparisons: 0, + swaps: 0, + should_print, + normal: NormalSelect::new(should_print), + } + } + + fn select_mut(&mut self, list: &mut Vec, order_statistic: usize) -> u64 { + self._select(list, 0, list.len() - 1, order_statistic).1 + } + + fn num_comp(&self) -> u64 { + self.comparisons + } + + fn num_swap(&self) -> u64 { + self.swaps + } + + fn reset_state(&mut self) { + self.comparisons = 0; + self.swaps = 0; + self.normal.reset_state(); + } +} diff --git a/libsort/src/hybrid_sort.rs b/libsort/src/hybrid_sort.rs index e815bf5..75a2f33 100644 --- a/libsort/src/hybrid_sort.rs +++ b/libsort/src/hybrid_sort.rs @@ -32,14 +32,18 @@ impl Sort for HybridSort { if self.should_print { println!(""); } self.insertion.sort_mut(list); if self.should_print { println!(""); } + self.comparisons += self.insertion.num_comp(); self.swaps += self.insertion.num_swap(); + self.insertion.reset_state(); return; } let pivot = self.quick.lomuto_partition(list); + self.comparisons += self.quick.num_comp(); self.swaps += self.quick.num_swap(); + self.quick.reset_state(); if self.should_print { println!(""); @@ -64,5 +68,7 @@ impl Sort for HybridSort { fn reset_state(&mut self) { self.comparisons = 0; self.swaps = 0; + self.insertion.reset_state(); + self.quick.reset_state(); } } diff --git a/libsort/src/my_sort.rs b/libsort/src/my_sort.rs index 8427f03..7c8ecf5 100644 --- a/libsort/src/my_sort.rs +++ b/libsort/src/my_sort.rs @@ -51,6 +51,7 @@ impl MySort { self.comparisons += self.merge.num_comp(); self.swaps += self.merge.num_swap(); + self.merge.reset_state(); } else if mid >= s { self._mysort(list, low, s - 1, e, s - 1); @@ -59,6 +60,7 @@ impl MySort { self.comparisons += self.merge.num_comp(); self.swaps += self.merge.num_swap(); + self.merge.reset_state(); } else { let i = self.extend_run_left(list, low); let j = self.extend_run_right(list, high); @@ -75,6 +77,7 @@ impl MySort { self.comparisons += self.merge.num_comp(); self.swaps += self.merge.num_swap(); + self.merge.reset_state(); } else { self._mysort(list, low, j, e, i); self._mysort(list, j + 1, high, j + 1, s); @@ -84,6 +87,7 @@ impl MySort { self.comparisons += self.merge.num_comp(); self.swaps += self.merge.num_swap(); + self.merge.reset_state(); } } } @@ -113,5 +117,6 @@ impl Sort for MySort { fn reset_state(&mut self) { self.comparisons = 0; self.swaps = 0; + self.merge.reset_state(); } } diff --git a/libsort/src/quick_sort.rs b/libsort/src/quick_sort.rs index beb558c..18d8fdb 100644 --- a/libsort/src/quick_sort.rs +++ b/libsort/src/quick_sort.rs @@ -37,7 +37,7 @@ impl QuickSort { } if swap != pivot { - list.swap(swap, pivot); + self.swap(list, swap, pivot); } swap as u64