borked radix sort

This commit is contained in:
Rolf Martin Glomsrud 2023-03-04 01:52:39 +01:00
parent 79dc592a40
commit 25e4183e7a
9 changed files with 118 additions and 55 deletions

12
Cargo.lock generated
View file

@ -6,6 +6,7 @@ version = 3
name = "BeepSortMacroQuad" name = "BeepSortMacroQuad"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"async-recursion",
"async-trait", "async-trait",
"macroquad", "macroquad",
"tokio-test", "tokio-test",
@ -28,6 +29,17 @@ dependencies = [
"version_check", "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]] [[package]]
name = "async-stream" name = "async-stream"
version = "0.3.4" version = "0.3.4"

View file

@ -9,6 +9,6 @@ edition = "2021"
macroquad = "0.3.25" macroquad = "0.3.25"
async-trait = "0.1.64" async-trait = "0.1.64"
tokio-test = "*" tokio-test = "*"
async-recursion = "1.0.2"
[profile.release] [profile.release]
opt-level=3 opt-level=3

View file

@ -4,14 +4,14 @@ use macroquad::rand;
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct Bar { pub struct Bar {
pub position:i32, pub position:usize,
pub color:color::Color pub color:color::Color
} }
impl Bar{ impl Bar{
pub fn new(position:i32, hsl_color:f32) -> Self{ pub fn new(position:usize, hsl_color:f32) -> Self{
Bar{ Bar{
position, position,
color: color::hsl_to_rgb((hsl_color as f32) , 1.0, 0.5), color: color::hsl_to_rgb((hsl_color as f32) , 1.0, 0.5),

View file

@ -35,7 +35,7 @@ pub struct GuiVec{
#[async_trait] #[async_trait]
pub trait SortingList{ pub trait SortingList{
fn new(length:i32, delay:f32) -> Self; fn new(length:usize, delay:f32) -> Self;
fn len(&self) -> usize; fn len(&self) -> usize;
@ -52,7 +52,7 @@ pub trait SortingList{
fn lessThan(&mut self, a:usize, b:usize) -> bool; 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; fn isSorted(&mut self) -> bool;
@ -65,7 +65,7 @@ pub trait SortingList{
#[async_trait] #[async_trait]
impl SortingList for GuiVec{ 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 colorStep = 360./length as f32;
let mut list:Vec<Bar> = vec!(); let mut list:Vec<Bar> = vec!();
for i in 1..length+1 { for i in 1..length+1 {
@ -181,7 +181,7 @@ impl SortingList for GuiVec{
self.comps += 1; self.comps += 1;
return self.get(a).position < self.get(b).position 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; self.comps += 1;
return self.get(a).position <= b return self.get(a).position <= b
} }
@ -228,10 +228,10 @@ pub struct NonGuiVec{
} }
#[async_trait] #[async_trait]
impl SortingList for NonGuiVec{ impl SortingList for NonGuiVec{
fn new(length:i32, delay:f32) -> Self{ fn new(length:usize, delay:f32) -> Self{
let mut list = Vec::new(); let mut list = Vec::new();
for i in 0..(length as usize){ 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 } NonGuiVec { list: list }
} }
@ -265,7 +265,7 @@ impl SortingList for NonGuiVec{
return self.get(a).position < self.get(b).position 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 return self.get(a).position <= b
} }
fn isSorted(&mut self) -> bool{ fn isSorted(&mut self) -> bool{

View file

@ -19,7 +19,7 @@ pub struct Algorithm{
impl 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); let mut list:GuiVec = SortingList::new(length, delay);
list.randomize(); list.randomize();

View file

@ -4,8 +4,8 @@ use crate::GuiHookVec::SortingList;
pub async fn binaryHeap(list:&mut impl SortingList){ pub async fn binaryHeap(list:&mut impl SortingList){
let mut indexMap:HashMap<i32, usize> = HashMap::new(); let mut indexMap:HashMap<usize, usize> = HashMap::new();
let mut binHeap:BinaryHeap<i32> = BinaryHeap::new(); let mut binHeap:BinaryHeap<usize> = BinaryHeap::new();
let mut ind = 0; let mut ind = 0;
for bar in list.elements(){ for bar in list.elements(){

View file

@ -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; let mut pIndex = low;
for i in low..high{ for i in low..high{

View file

@ -1,3 +1,5 @@
use async_recursion::async_recursion;
use crate::GuiHookVec::SortingList; use crate::GuiHookVec::SortingList;
@ -5,52 +7,89 @@ use crate::GuiHookVec::SortingList;
pub async fn radixSort(list:&mut impl SortingList) { pub async fn radixSort(list:&mut impl SortingList) {
let mut max = usize::MIN; 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(){ if max < i.len(){
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::<Vec<char>>();
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<usize> = 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<usize> = 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)] #[cfg(test)]
#[allow(non_snake_case)] #[allow(non_snake_case)]
mod tests { mod tests {
@ -67,8 +106,20 @@ use super::*;
#[test] #[test]
fn radixsort_correct() { 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)); aw!(radixSort(&mut list));
assert_eq!( list.isSorted(), true); assert_eq!( list.isSorted(), true);
} }
}
#[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);
}
}

View file

@ -15,7 +15,7 @@ use macroquad::ui::root_ui;
#[macroquad::main("BeepSort")] #[macroquad::main("BeepSort")]
async fn main() { async fn main() {
let mut length = 1; let mut length = 1_usize;
let mut lengthString = "100".to_owned(); let mut lengthString = "100".to_owned();
let mut delay = 0.; let mut delay = 0.;
let mut delayText = "1".to_owned(); let mut delayText = "1".to_owned();
@ -29,7 +29,7 @@ async fn main() {
Ok(a) => a/1000., Ok(a) => a/1000.,
Err(error)=> {0.1} Err(error)=> {0.1}
}; };
length = match lengthString.parse::<i32>(){ length = match lengthString.parse::<usize>(){
Ok(a) => a, Ok(a) => a,
Err(error)=> {100} Err(error)=> {100}
}; };