From 9c22f0dbb052cd84a0d9898051115609164c8cb0 Mon Sep 17 00:00:00 2001 From: jacekpoz Date: Mon, 6 May 2024 20:21:11 +0200 Subject: [PATCH] big refactor --- .gitignore | 1 + lab2/zad1/gen_asc/Cargo.toml | 2 +- lab2/zad1/gen_desc/Cargo.toml | 2 +- lab2/zad1/gen_rand/Cargo.toml | 2 +- lab2/zad1/hybridsort/Cargo.toml | 2 +- lab2/zad1/hybridsort/src/main.rs | 10 +- lab2/zad1/insertionsort/Cargo.toml | 2 +- lab2/zad1/insertionsort/src/main.rs | 10 +- lab2/zad1/libsort/src/lib.rs | 154 ---------------------- lab2/zad1/quicksort/Cargo.toml | 2 +- lab2/zad1/quicksort/src/main.rs | 10 +- libgen/.gitignore | 1 + {lab2/zad1/libgen => libgen}/Cargo.lock | 0 {lab2/zad1/libgen => libgen}/Cargo.toml | 0 {lab2/zad1/libgen => libgen}/src/lib.rs | 0 libsort/.gitignore | 1 + {lab2/zad1/libsort => libsort}/Cargo.lock | 0 {lab2/zad1/libsort => libsort}/Cargo.toml | 0 libsort/src/hybrid_sort.rs | 76 +++++++++++ libsort/src/insertion_sort.rs | 62 +++++++++ libsort/src/lib.rs | 31 +++++ libsort/src/quick_sort.rs | 93 +++++++++++++ 22 files changed, 289 insertions(+), 172 deletions(-) delete mode 100644 lab2/zad1/libsort/src/lib.rs create mode 100644 libgen/.gitignore rename {lab2/zad1/libgen => libgen}/Cargo.lock (100%) rename {lab2/zad1/libgen => libgen}/Cargo.toml (100%) rename {lab2/zad1/libgen => libgen}/src/lib.rs (100%) create mode 100644 libsort/.gitignore rename {lab2/zad1/libsort => libsort}/Cargo.lock (100%) rename {lab2/zad1/libsort => libsort}/Cargo.toml (100%) create mode 100644 libsort/src/hybrid_sort.rs create mode 100644 libsort/src/insertion_sort.rs create mode 100644 libsort/src/lib.rs create mode 100644 libsort/src/quick_sort.rs diff --git a/.gitignore b/.gitignore index ff7692f..fc78039 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ l1 .ccls-cache/ +*/target diff --git a/lab2/zad1/gen_asc/Cargo.toml b/lab2/zad1/gen_asc/Cargo.toml index 950482e..c97c3d5 100644 --- a/lab2/zad1/gen_asc/Cargo.toml +++ b/lab2/zad1/gen_asc/Cargo.toml @@ -4,4 +4,4 @@ version = "0.1.0" edition = "2021" [dependencies] -libgen = { path = "../libgen" } +libgen = { path = "../../../libgen" } diff --git a/lab2/zad1/gen_desc/Cargo.toml b/lab2/zad1/gen_desc/Cargo.toml index d46effa..ff95a9d 100644 --- a/lab2/zad1/gen_desc/Cargo.toml +++ b/lab2/zad1/gen_desc/Cargo.toml @@ -4,4 +4,4 @@ version = "0.1.0" edition = "2021" [dependencies] -libgen = { path = "../libgen" } +libgen = { path = "../../../libgen" } diff --git a/lab2/zad1/gen_rand/Cargo.toml b/lab2/zad1/gen_rand/Cargo.toml index 8d566a2..45cb473 100644 --- a/lab2/zad1/gen_rand/Cargo.toml +++ b/lab2/zad1/gen_rand/Cargo.toml @@ -4,4 +4,4 @@ version = "0.1.0" edition = "2021" [dependencies] -libgen = { path = "../libgen" } +libgen = { path = "../../../libgen" } diff --git a/lab2/zad1/hybridsort/Cargo.toml b/lab2/zad1/hybridsort/Cargo.toml index 02548ff..9f6e2e9 100644 --- a/lab2/zad1/hybridsort/Cargo.toml +++ b/lab2/zad1/hybridsort/Cargo.toml @@ -4,4 +4,4 @@ version = "0.1.0" edition = "2021" [dependencies] -libsort = { path = "../libsort" } +libsort = { path = "../../../libsort" } diff --git a/lab2/zad1/hybridsort/src/main.rs b/lab2/zad1/hybridsort/src/main.rs index 7cb7fa5..2ab4230 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, is_sorted, print_list}; +use libsort::{hybrid_sort::HybridSort, is_sorted, print_list, Sort}; fn main() -> io::Result<()> { let mut buffer = String::new(); @@ -33,7 +33,9 @@ fn main() -> io::Result<()> { println!(); } - let res = hybrid_sort(&mut list, 8, print); + let mut hybrid = HybridSort::new(8, print); + + hybrid.sort_mut(&mut list); if print { println!(); @@ -44,8 +46,8 @@ fn main() -> io::Result<()> { print_list(&list); } - println!("swaps: {}", res.swaps); - println!("comparisons: {}", res.comparisons); + println!("swaps: {}", hybrid.num_swap()); + println!("comparisons: {}", hybrid.num_comp()); println!("is sorted: {}", is_sorted(&list)); diff --git a/lab2/zad1/insertionsort/Cargo.toml b/lab2/zad1/insertionsort/Cargo.toml index ae4d971..45ebe82 100644 --- a/lab2/zad1/insertionsort/Cargo.toml +++ b/lab2/zad1/insertionsort/Cargo.toml @@ -4,4 +4,4 @@ version = "0.1.0" edition = "2021" [dependencies] -libsort = { path = "../libsort" } +libsort = { path = "../../../libsort" } diff --git a/lab2/zad1/insertionsort/src/main.rs b/lab2/zad1/insertionsort/src/main.rs index 5524375..4a03e43 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, is_sorted, print_list}; +use libsort::{insertion_sort::InsertionSort, is_sorted, print_list, Sort}; fn main() -> io::Result<()> { let mut buffer = String::new(); @@ -33,7 +33,9 @@ fn main() -> io::Result<()> { println!(); } - let res = insertion_sort(&mut list, print); + let mut insertion = InsertionSort::new(print); + + insertion.sort_mut(&mut list); if print { println!(); @@ -44,8 +46,8 @@ fn main() -> io::Result<()> { print_list(&list); } - println!("swaps: {}", res.swaps); - println!("comparisons: {}", res.comparisons); + println!("swaps: {}", insertion.num_swap()); + println!("comparisons: {}", insertion.num_comp()); println!("is sorted: {}", is_sorted(&list)); diff --git a/lab2/zad1/libsort/src/lib.rs b/lab2/zad1/libsort/src/lib.rs deleted file mode 100644 index ebc9ce6..0000000 --- a/lab2/zad1/libsort/src/lib.rs +++ /dev/null @@ -1,154 +0,0 @@ -pub fn print_list(list: &[u64]) { - print!("["); - list.iter() - .enumerate() - .for_each(|(i, x)| { - if *x < 10 { - print!("0"); - } - print!("{}", x); - if i != list.len() - 1 { - print!(", ") - } - }); - println!("]"); -} - -#[derive(PartialEq)] -pub enum CompareResult { - LESS, EQUAL, GREATER -} - -pub fn compare(a: u64, b: u64, comparisons: &mut u64) -> CompareResult { - *comparisons += 1; - if a < b { - CompareResult::LESS - } else if a > b { - CompareResult::GREATER - } else { - CompareResult::EQUAL - } -} - -pub fn swap(list: &mut [u64], i: usize, j: usize, swaps: &mut u64) { - *swaps += 1; - list.swap(i, j); -} - -#[derive(Debug, Clone)] -pub struct SortResult { - pub comparisons: u64, - pub swaps: u64, -} - -impl Default for SortResult { - fn default() -> Self { - Self { comparisons: 0, swaps: 0 } - } -} - -use CompareResult::*; - -pub fn insertion_sort(list: &mut [u64], print: bool) -> SortResult { - let mut res = SortResult::default(); - for i in 1..list.len() { - let mut j = i as usize; - - while j > 0 && compare(list[j - 1], list[j], &mut res.comparisons) == GREATER { - swap(list, j - 1, j, &mut res.swaps); - j -= 1; - } - - if print { print_list(&list); } - } - - res -} - -pub fn lomuto_partition(list: &mut [u64], res: &mut SortResult) -> u64 { - let mut _res = SortResult::default(); - - let pivot = list.len() - 1; - let mut _swap = 0; - - for i in 0..pivot { - if compare(list[i as usize], list[pivot as usize], &mut _res.comparisons) == LESS { - if _swap != i { - swap(list, _swap, i, &mut _res.swaps); - } - _swap += 1; - } - } - - if _swap != pivot { - list.swap(_swap, pivot); - } - - res.swaps += _res.swaps; - res.comparisons += _res.comparisons; - - _swap as u64 -} - -pub fn quick_sort(list: &mut [u64], print: bool) -> SortResult { - let mut res = SortResult::default(); - - if list.len() > 1 { - let pivot = lomuto_partition(list, &mut res); - - if print { - println!("pivot = {pivot}:"); - print_list(&list); - } - - let res1 = quick_sort(&mut list[..pivot as usize], print); - res.swaps += res1.swaps; - res.comparisons += res1.comparisons; - - let res2 = quick_sort(&mut list[pivot as usize + 1..], print); - res.swaps += res2.swaps; - res.comparisons += res2.comparisons; - } - - res -} - -pub fn hybrid_sort(list: &mut [u64], switch: u64, print: bool) -> SortResult { - let mut res = SortResult::default(); - - if list.len() as u64 <= switch { - if print { println!(""); } - let insertion_res = insertion_sort(list, print); - if print { println!(""); } - return insertion_res; - } - - let pivot = lomuto_partition(list, &mut res); - - if print { - println!(""); - println!("pivot = {pivot}:"); - print_list(&list); - println!(""); - } - - let res1 = hybrid_sort(&mut list[..pivot as usize], switch, print); - res.swaps += res1.swaps; - res.comparisons += res1.comparisons; - - let res2 = hybrid_sort(&mut list[pivot as usize + 1..], switch, print); - res.swaps += res2.swaps; - res.comparisons += res2.comparisons; - - res -} - -pub fn is_sorted(list: &[u64]) -> bool { - for i in 0..(list.len() - 1) { - if list[i] > list[i + 1] { - return false; - } - } - - true -} diff --git a/lab2/zad1/quicksort/Cargo.toml b/lab2/zad1/quicksort/Cargo.toml index 9fb3c6e..29ae216 100644 --- a/lab2/zad1/quicksort/Cargo.toml +++ b/lab2/zad1/quicksort/Cargo.toml @@ -4,4 +4,4 @@ version = "0.1.0" edition = "2021" [dependencies] -libsort = { path = "../libsort" } +libsort = { path = "../../../libsort" } diff --git a/lab2/zad1/quicksort/src/main.rs b/lab2/zad1/quicksort/src/main.rs index 8f7ce3f..98d7e88 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}; +use libsort::{is_sorted, print_list, quick_sort::QuickSort, Sort}; fn main() -> io::Result<()> { let mut buffer = String::new(); @@ -33,7 +33,9 @@ fn main() -> io::Result<()> { println!(); } - let res = quick_sort(&mut list, print); + let mut quick = QuickSort::new(print); + + quick.sort_mut(&mut list); if print { println!(); @@ -44,8 +46,8 @@ fn main() -> io::Result<()> { print_list(&list); } - println!("swaps: {}", res.swaps); - println!("comparisons: {}", res.comparisons); + println!("swaps: {}", quick.num_swap()); + println!("comparisons: {}", quick.num_comp()); println!("is sorted: {}", is_sorted(&list)); diff --git a/libgen/.gitignore b/libgen/.gitignore new file mode 100644 index 0000000..eb5a316 --- /dev/null +++ b/libgen/.gitignore @@ -0,0 +1 @@ +target diff --git a/lab2/zad1/libgen/Cargo.lock b/libgen/Cargo.lock similarity index 100% rename from lab2/zad1/libgen/Cargo.lock rename to libgen/Cargo.lock diff --git a/lab2/zad1/libgen/Cargo.toml b/libgen/Cargo.toml similarity index 100% rename from lab2/zad1/libgen/Cargo.toml rename to libgen/Cargo.toml diff --git a/lab2/zad1/libgen/src/lib.rs b/libgen/src/lib.rs similarity index 100% rename from lab2/zad1/libgen/src/lib.rs rename to libgen/src/lib.rs diff --git a/libsort/.gitignore b/libsort/.gitignore new file mode 100644 index 0000000..eb5a316 --- /dev/null +++ b/libsort/.gitignore @@ -0,0 +1 @@ +target diff --git a/lab2/zad1/libsort/Cargo.lock b/libsort/Cargo.lock similarity index 100% rename from lab2/zad1/libsort/Cargo.lock rename to libsort/Cargo.lock diff --git a/lab2/zad1/libsort/Cargo.toml b/libsort/Cargo.toml similarity index 100% rename from lab2/zad1/libsort/Cargo.toml rename to libsort/Cargo.toml diff --git a/libsort/src/hybrid_sort.rs b/libsort/src/hybrid_sort.rs new file mode 100644 index 0000000..0f7940c --- /dev/null +++ b/libsort/src/hybrid_sort.rs @@ -0,0 +1,76 @@ +use crate::{insertion_sort::InsertionSort, quick_sort::QuickSort, Sort}; + +pub struct HybridSort { + comparisons: u64, + swaps: u64, + should_print: bool, + insertion: InsertionSort, + quick: QuickSort, + switch: u64, +} + +impl HybridSort { + pub fn new(switch: u64, should_print: bool) -> Self { + Self { + comparisons: 0, + swaps: 0, + should_print, + insertion: InsertionSort::new(should_print), + quick: QuickSort::new(should_print), + switch, + } + } +} + +impl Sort for HybridSort { + fn new(should_print: bool) -> Self { + Self::new(16, should_print) + } + + fn sort_mut(&mut self, list: &mut Vec) { + if list.len() as u64 <= self.switch { + 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(); + return; + } + + let pivot = self.quick.lomuto_partition(list); + self.comparisons += self.quick.num_comp(); + self.swaps += self.quick.num_swap(); + + if self.should_print { + println!(""); + println!("pivot = {pivot}:"); + println!("{:?}", list); + println!(""); + } + + let mut vec = Vec::new(); + for i in 0..pivot as usize { + vec.push(list[i]); + } + self.sort_mut(&mut vec); + + vec.clear(); + for i in (pivot as usize + 1)..list.len() { + vec.push(list[i]); + } + self.sort_mut(&mut vec); + } + + 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; + } +} diff --git a/libsort/src/insertion_sort.rs b/libsort/src/insertion_sort.rs new file mode 100644 index 0000000..f368e3f --- /dev/null +++ b/libsort/src/insertion_sort.rs @@ -0,0 +1,62 @@ +use crate::{CompareResult, Sort}; + +pub struct InsertionSort { + comparisons: u64, + swaps: u64, + should_print: bool, +} + +impl InsertionSort { + 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 + } + } +} + +impl Sort for InsertionSort { + fn new(should_print: bool) -> Self { + Self { + comparisons: 0, + swaps: 0, + should_print, + } + } + + fn sort_mut(&mut self, list: &mut Vec) { + + for i in 1..list.len() { + let mut j = i as usize; + + use CompareResult::*; + while j > 0 && self.compare(list[j - 1], list[j]) == GREATER { + self.swap(list, j - 1, j); + j -= 1; + } + + if self.should_print { println!("{:?}", list); } + } + } + + 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; + } +} diff --git a/libsort/src/lib.rs b/libsort/src/lib.rs new file mode 100644 index 0000000..d0828a2 --- /dev/null +++ b/libsort/src/lib.rs @@ -0,0 +1,31 @@ +pub mod insertion_sort; +pub mod hybrid_sort; +pub mod quick_sort; + +pub trait Sort { + fn new(should_print: bool) -> Self; + fn sort_mut(&mut self, list: &mut Vec); + fn sort(&mut self, list: &Vec) -> Vec { + let mut list = list.clone(); + self.sort_mut(&mut list); + list + } + fn num_comp(&self) -> u64; + fn num_swap(&self) -> u64; + fn reset_state(&mut self); +} + +#[derive(PartialEq)] +pub enum CompareResult { + LESS, EQUAL, GREATER +} + +pub fn is_sorted(list: &[u64]) -> bool { + for i in 0..(list.len() - 1) { + if list[i] > list[i + 1] { + return false; + } + } + + true +} diff --git a/libsort/src/quick_sort.rs b/libsort/src/quick_sort.rs new file mode 100644 index 0000000..6bbb68a --- /dev/null +++ b/libsort/src/quick_sort.rs @@ -0,0 +1,93 @@ +use crate::{CompareResult, Sort}; + +pub struct QuickSort { + comparisons: u64, + swaps: u64, + should_print: bool, +} + +impl QuickSort { + 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 lomuto_partition(&mut self, list: &mut Vec) -> u64 { + let pivot = list.len() - 1; + let mut swap = 0; + + for i in 0..pivot { + use CompareResult::*; + if self.compare(list[i as usize], list[pivot as usize]) == LESS { + if swap != i { + self.swap(list, swap, i); + } + swap += 1; + } + } + + if swap != pivot { + list.swap(swap, pivot); + } + + swap as u64 + } + +} + +impl Sort for QuickSort { + fn new(should_print: bool) -> Self { + Self { + comparisons: 0, + swaps: 0, + should_print, + } + } + + fn sort_mut(&mut self, list: &mut Vec) { + if list.len() > 1 { + let pivot = self.lomuto_partition(list); + + if self.should_print { + println!("pivot = {pivot}:"); + println!("{:?}", list); + } + + let mut vec = Vec::new(); + for i in 0..pivot as usize { + vec.push(list[i]); + } + self.sort_mut(&mut vec); + + vec.clear(); + for i in (pivot as usize + 1)..list.len() { + vec.push(list[i]); + } + self.sort_mut(&mut vec); + } + } + + 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; + } +} +