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"
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"

View file

@ -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

View file

@ -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),

View file

@ -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<Bar> = 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{

View file

@ -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();

View file

@ -4,8 +4,8 @@ use crate::GuiHookVec::SortingList;
pub async fn binaryHeap(list:&mut impl SortingList){
let mut indexMap:HashMap<i32, usize> = HashMap::new();
let mut binHeap:BinaryHeap<i32> = BinaryHeap::new();
let mut indexMap:HashMap<usize, usize> = HashMap::new();
let mut binHeap:BinaryHeap<usize> = BinaryHeap::new();
let mut ind = 0;
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;
for i in low..high{

View file

@ -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::<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)]
#[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);
}
}
#[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")]
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::<i32>(){
length = match lengthString.parse::<usize>(){
Ok(a) => a,
Err(error)=> {100}
};