From 25e4183e7aa7ef2e34c3703de621e99aa80ad971 Mon Sep 17 00:00:00 2001 From: polsevev Date: Sat, 4 Mar 2023 01:52:39 +0100 Subject: [PATCH] borked radix sort --- Cargo.lock | 12 ++++ Cargo.toml | 2 +- src/BarPlugin.rs | 4 +- src/GuiHookVec.rs | 14 ++-- src/algorithm.rs | 2 +- src/algorithm/binaryHeap.rs | 4 +- src/algorithm/quickSort.rs | 2 +- src/algorithm/radixSort.rs | 129 +++++++++++++++++++++++++----------- src/main.rs | 4 +- 9 files changed, 118 insertions(+), 55 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ff94436..0fc4423 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6,6 +6,7 @@ version = 3 name = "BeepSortMacroQuad" version = "0.1.0" dependencies = [ + "async-recursion", "async-trait", "macroquad", "tokio-test", @@ -28,6 +29,17 @@ dependencies = [ "version_check", ] +[[package]] +name = "async-recursion" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b015a331cc64ebd1774ba119538573603427eaace0a1950c423ab971f903796" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "async-stream" version = "0.3.4" diff --git a/Cargo.toml b/Cargo.toml index 66b4feb..b030289 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,6 @@ edition = "2021" macroquad = "0.3.25" async-trait = "0.1.64" tokio-test = "*" - +async-recursion = "1.0.2" [profile.release] opt-level=3 diff --git a/src/BarPlugin.rs b/src/BarPlugin.rs index 83be026..c9dcadf 100644 --- a/src/BarPlugin.rs +++ b/src/BarPlugin.rs @@ -4,14 +4,14 @@ use macroquad::rand; #[derive(Debug, Clone, Copy)] pub struct Bar { - pub position:i32, + pub position:usize, pub color:color::Color } impl Bar{ - pub fn new(position:i32, hsl_color:f32) -> Self{ + pub fn new(position:usize, hsl_color:f32) -> Self{ Bar{ position, color: color::hsl_to_rgb((hsl_color as f32) , 1.0, 0.5), diff --git a/src/GuiHookVec.rs b/src/GuiHookVec.rs index 7302bb3..576c157 100644 --- a/src/GuiHookVec.rs +++ b/src/GuiHookVec.rs @@ -35,7 +35,7 @@ pub struct GuiVec{ #[async_trait] pub trait SortingList{ - fn new(length:i32, delay:f32) -> Self; + fn new(length:usize, delay:f32) -> Self; fn len(&self) -> usize; @@ -52,7 +52,7 @@ pub trait SortingList{ fn lessThan(&mut self, a:usize, b:usize) -> bool; - fn lessThanEqual(&mut self, a:usize, b:i32) -> bool; + fn lessThanEqual(&mut self, a:usize, b:usize) -> bool; fn isSorted(&mut self) -> bool; @@ -65,7 +65,7 @@ pub trait SortingList{ #[async_trait] impl SortingList for GuiVec{ - fn new(length:i32, delay:f32) -> Self { + fn new(length:usize, delay:f32) -> Self { let colorStep = 360./length as f32; let mut list:Vec = vec!(); for i in 1..length+1 { @@ -181,7 +181,7 @@ impl SortingList for GuiVec{ self.comps += 1; return self.get(a).position < self.get(b).position } - fn lessThanEqual(&mut self, a:usize, b:i32) -> bool{ + fn lessThanEqual(&mut self, a:usize, b:usize) -> bool{ self.comps += 1; return self.get(a).position <= b } @@ -228,10 +228,10 @@ pub struct NonGuiVec{ } #[async_trait] impl SortingList for NonGuiVec{ - fn new(length:i32, delay:f32) -> Self{ + fn new(length:usize, delay:f32) -> Self{ let mut list = Vec::new(); for i in 0..(length as usize){ - list.push(Bar::new(i as i32, i as f32)) + list.push(Bar::new(i, i as f32)) } NonGuiVec { list: list } } @@ -265,7 +265,7 @@ impl SortingList for NonGuiVec{ return self.get(a).position < self.get(b).position } - fn lessThanEqual(&mut self, a:usize, b:i32) -> bool{ + fn lessThanEqual(&mut self, a:usize, b:usize) -> bool{ return self.get(a).position <= b } fn isSorted(&mut self) -> bool{ diff --git a/src/algorithm.rs b/src/algorithm.rs index c789836..36367b1 100644 --- a/src/algorithm.rs +++ b/src/algorithm.rs @@ -19,7 +19,7 @@ pub struct Algorithm{ impl Algorithm{ - pub async fn run(length:i32, delay:f32, functionName:String){ + pub async fn run(length:usize, delay:f32, functionName:String){ let mut list:GuiVec = SortingList::new(length, delay); list.randomize(); diff --git a/src/algorithm/binaryHeap.rs b/src/algorithm/binaryHeap.rs index 89ba758..baa0f07 100644 --- a/src/algorithm/binaryHeap.rs +++ b/src/algorithm/binaryHeap.rs @@ -4,8 +4,8 @@ use crate::GuiHookVec::SortingList; pub async fn binaryHeap(list:&mut impl SortingList){ - let mut indexMap:HashMap = HashMap::new(); - let mut binHeap:BinaryHeap = BinaryHeap::new(); + let mut indexMap:HashMap = HashMap::new(); + let mut binHeap:BinaryHeap = BinaryHeap::new(); let mut ind = 0; for bar in list.elements(){ diff --git a/src/algorithm/quickSort.rs b/src/algorithm/quickSort.rs index 670c2ec..8f6eeb2 100644 --- a/src/algorithm/quickSort.rs +++ b/src/algorithm/quickSort.rs @@ -31,7 +31,7 @@ pub async fn quickSort(list:&mut impl SortingList) { -async fn partition(list:&mut impl SortingList, mut low:usize, mut high:usize, p:i32) -> i32{ +async fn partition(list:&mut impl SortingList, mut low:usize, mut high:usize, p:usize) -> i32{ let mut pIndex = low; for i in low..high{ diff --git a/src/algorithm/radixSort.rs b/src/algorithm/radixSort.rs index cebfde8..c402fb3 100644 --- a/src/algorithm/radixSort.rs +++ b/src/algorithm/radixSort.rs @@ -1,3 +1,5 @@ +use async_recursion::async_recursion; + use crate::GuiHookVec::SortingList; @@ -5,52 +7,89 @@ use crate::GuiHookVec::SortingList; pub async fn radixSort(list:&mut impl SortingList) { let mut max = usize::MIN; - for i in list.getListClone().into_iter().map(|x| x.position.to_string()){ + for i in list.getListClone().into_iter().map(|x| format!("{:b}",x.position)){ if max < i.len(){ max = i.len(); } } - - for i in 0..(max){ - if radix(list, i).await {return}; - } -} - -async fn radix(list:&mut impl SortingList, radix:usize) -> bool{ - let mut bucket = vec![vec![];10]; - - for (i, bar) in list.elements().enumerate(){ - - let cur = bar.position.to_string().chars().rev().collect::>(); - if cur.len() > radix{ - bucket[cur[radix].to_digit(10).unwrap() as usize].push(i); - }else{ - bucket[0].push(i); - } - - } - - - let mut sortedIndexes = Vec::new(); - for elements in bucket.into_iter(){ - for i in elements{ - sortedIndexes.push(i); - } - } - - let mut listClone = list.getListClone(); - let mut count = 0; - for i in sortedIndexes.clone(){ - if list.set(count, listClone[i]).await {return true}; - count += 1; - - } - false + + let mut stack:Vec<(usize, usize)> = Vec::new(); + let mut stack2:Vec<(usize,usize)> = Vec::new(); + stack.push((0, list.len())); + for i in (0..max).rev(){ + + + + while stack.len() > 0{ + let cur = stack.pop().unwrap(); + print!("{:?}", cur); + match radix(list, i, cur.0, cur.1).await{ + Some((initial, switch, max)) => { + if initial < switch{ + stack2.push((initial, switch)); + } + if switch < max{ + + stack2.push((switch, max)); + } + + }, + None => return + } + } + stack = stack2.clone(); + } } +async fn radix(list:&mut impl SortingList, radix:usize, mut minBoundry:usize, mut maxBoundry:usize) -> Option<(usize,usize,usize)>{ + let initialMin = minBoundry.clone(); + let initialMax = maxBoundry.clone(); + + // let mut bitVec:Vec = Vec::new(); + // for i in 0..list.len(){ + // let currentBit = get_bit_at(list.get(i).position, radix); + // bitVec.push(if currentBit {1} else {0}); + // } + // println!("{:?}", bitVec); + + loop{ + if maxBoundry == minBoundry{ + break + } + let currentBit = get_bit_at(list.get(minBoundry).position, radix); + + if currentBit{ + if list.swap(minBoundry, maxBoundry-1).await {return None}; + maxBoundry -= 1; + }else{ + if list.swap(minBoundry, minBoundry).await {return None}; + + minBoundry += 1; + } + } + + // let mut bitVec:Vec = Vec::new(); + // for i in 0..list.len(){ + // let currentBit = get_bit_at(list.get(i).position, radix); + // bitVec.push(if currentBit {1} else {0}); + // } + + + Some((initialMin, minBoundry, initialMax)) +} +fn get_bit_at(input: usize, n: usize) -> bool { + println!("{} >= {}", format!("{:b}", input).len(), n); + if format!("{:b}", input).len() <= n{ + false + }else{ + input & (1 << n) != 0 + } + + +} #[cfg(test)] #[allow(non_snake_case)] mod tests { @@ -67,8 +106,20 @@ use super::*; #[test] fn radixsort_correct() { - let mut list:NonGuiVec = SortingList::new(10000,0.0); + let mut list:NonGuiVec = SortingList::new(1000,0.0); aw!(radixSort(&mut list)); assert_eq!( list.isSorted(), true); } -} \ No newline at end of file + + #[test] + fn get_bit_at_test(){ + let num = 0b0001; + let othernum = 2; + assert_eq!(get_bit_at(num, 0), true); + assert_eq!(get_bit_at(num, 1), false); + assert_eq!(get_bit_at(othernum, 1), true); + assert_eq!(get_bit_at(othernum, 2), false); + assert_eq!(get_bit_at(othernum, 3), false); + } +} + diff --git a/src/main.rs b/src/main.rs index 1dde168..686d7cc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,7 +15,7 @@ use macroquad::ui::root_ui; #[macroquad::main("BeepSort")] async fn main() { - let mut length = 1; + let mut length = 1_usize; let mut lengthString = "100".to_owned(); let mut delay = 0.; let mut delayText = "1".to_owned(); @@ -29,7 +29,7 @@ async fn main() { Ok(a) => a/1000., Err(error)=> {0.1} }; - length = match lengthString.parse::(){ + length = match lengthString.parse::(){ Ok(a) => a, Err(error)=> {100} };