This commit is contained in:
Rolf Martin Glomsrud 2023-03-03 01:20:12 +01:00
commit 0b68bb773f
6 changed files with 201 additions and 30 deletions

8
Cargo.lock generated
View file

@ -6,7 +6,7 @@ version = 3
name = "BeepSortMacroQuad"
version = "0.1.0"
dependencies = [
"async-recursion",
"async-trait",
"macroquad",
]
@ -28,10 +28,10 @@ dependencies = [
]
[[package]]
name = "async-recursion"
version = "1.0.2"
name = "async-trait"
version = "0.1.64"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b015a331cc64ebd1774ba119538573603427eaace0a1950c423ab971f903796"
checksum = "1cd7fce9ba8c3c042128ce72d8b2ddbf3a05747efb67ea0313c635e10bda47a2"
dependencies = [
"proc-macro2",
"quote",

View file

@ -7,7 +7,7 @@ edition = "2021"
[dependencies]
macroquad = "0.3.25"
async-recursion = "1.0.2"
async-trait = "0.1.64"
[toolchain]
channel = "nightly"
[profile.release]

View file

@ -1,14 +1,17 @@
use crate::BarPlugin::Bar;
use crate::GuiHookVec;
use crate::GuiHookVec::GuiVec;
use crate::GuiHookVec::SortingList;
use async_recursion::async_recursion;
use macroquad::prelude::screen_width;
use macroquad::window::screen_height;
use std::collections::BinaryHeap;
use std::collections::HashMap;
use std::collections::HashSet;
use std::f32::consts::PI;
use std::hash::Hash;
#[derive(Debug, Clone)]
@ -19,8 +22,9 @@ pub struct Algorithm{
impl Algorithm{
pub async fn run(length:i32, delay:f32, functionName:String){
let mut list = GuiVec::new(length, delay);
let mut list:GuiVec = SortingList::new(length, delay);
list.randomize();
match functionName.as_str() {
"insertSort" => Algorithm::insertSort(&mut list).await,
@ -29,6 +33,7 @@ impl Algorithm{
"cocktailShaker" => Algorithm::cocktailShaker(&mut list).await,
"binaryHeap" => Algorithm::binaryHeap(&mut list).await,
"quickSort" => Algorithm::quickSort(&mut list).await,
"radixSort" => Algorithm::radixSort(&mut list).await,
_ => panic!("No algorithm with that name implemented!")
}
@ -39,7 +44,7 @@ impl Algorithm{
}
}
pub async fn insertSort(list:&mut GuiVec){
pub async fn insertSort(list:&mut impl SortingList){
for index in 0..list.len(){
let mut j = index;
while j>0 && list.lessThan(j, j-1){
@ -69,7 +74,7 @@ impl Algorithm{
}
*/
pub async fn bubbleSort(list:&mut GuiVec){
pub async fn bubbleSort(list:&mut impl SortingList){
let n = list.len();
for i in 0..n {
for j in 0..(n - i - 1) {
@ -81,7 +86,7 @@ impl Algorithm{
}
pub async fn bogoSort(list:&mut GuiVec){
pub async fn bogoSort(list:&mut impl SortingList){
loop{
if list.swap(0,0).await {return};
@ -92,7 +97,7 @@ impl Algorithm{
}
}
pub async fn cocktailShaker(list:&mut GuiVec){
pub async fn cocktailShaker(list:&mut impl SortingList){
let mut lowerBound = 0;
let mut upperBound = list.len()-1;
let mut swapped = true;
@ -123,7 +128,7 @@ impl Algorithm{
}
pub async fn binaryHeap(list:&mut GuiVec){
pub async fn binaryHeap(list:&mut impl SortingList){
let mut indexMap:HashMap<i32, usize> = HashMap::new();
let mut binHeap:BinaryHeap<i32> = BinaryHeap::new();
@ -147,7 +152,7 @@ impl Algorithm{
pub async fn partition(list:&mut GuiVec, mut low:usize, mut high:usize, p:i32) -> i32{
pub async fn partition(list:&mut impl SortingList, mut low:usize, mut high:usize, p:i32) -> i32{
let mut pIndex = low;
for i in low..high{
@ -162,7 +167,7 @@ impl Algorithm{
}
pub async fn quickSort(list:&mut GuiVec) {
pub async fn quickSort(list:&mut impl SortingList) {
let mut stack:Vec<(usize,usize)> = Vec::new();
let start = 0;
@ -173,7 +178,7 @@ impl Algorithm{
while stack.len() > 0{
let (start,end) = stack.pop().unwrap();
let p = list.list[end].position;
let p = list.get(end).position;
let temp = Algorithm::partition(list, start, end, p).await;
let pivot = if temp >= 0 {temp} else {return};
@ -189,6 +194,53 @@ impl Algorithm{
}
pub async fn radixSort(list:&mut impl SortingList) {
let mut max = usize::MAX;
for i in list.getListClone().into_iter().map(|x| x.position.to_string()){
if max < i.len(){
max = i.len();
}
}
for i in 0..(max){
if Algorithm::radix(list, i).await {return};
}
}
pub 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
}
}

View file

@ -2,7 +2,7 @@ use macroquad::color;
use macroquad::color_u8;
use macroquad::rand;
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Copy)]
pub struct Bar {
pub position:i32,
pub color:color::Color

View file

@ -2,6 +2,7 @@
use std::borrow::{Borrow, BorrowMut};
use std::ops::Add;
use std::path::Iter;
use async_trait::async_trait;
use macroquad::color::{BROWN, WHITE};
use macroquad::hash;
use macroquad::prelude::{clear_background, Vec2, BLACK};
@ -31,10 +32,40 @@ pub struct GuiVec{
skipped:i32
}
#[async_trait]
pub trait SortingList{
impl GuiVec{
fn new(length:i32, delay:f32) -> Self;
fn len(&self) -> usize;
async fn swap(&mut self, index1:usize, index2:usize) -> bool;
async fn draw(&mut self);
pub fn new(length:i32, delay:f32) -> Self {
fn randomize(&mut self);
fn elements(&mut self) -> std::slice::Iter<'_, Bar>;
fn get(&mut self, i:usize)-> &Bar;
fn lessThan(&mut self, a:usize, b:usize) -> bool;
fn lessThanEqual(&mut self, a:usize, b:i32) -> bool;
fn isSorted(&mut self) -> bool;
async fn set(&mut self, i:usize, elem:Bar) -> bool;
async fn show(&mut self);
fn getListClone(&self) -> Vec<Bar>;
}
#[async_trait]
impl SortingList for GuiVec{
fn new(length:i32, delay:f32) -> Self {
let colorStep = 360./length as f32;
let mut list:Vec<Bar> = vec!();
for i in 1..length+1 {
@ -55,7 +86,7 @@ impl GuiVec{
}
}
pub async fn draw(&mut self){
async fn draw(&mut self){
let mut frames = 0.0;
let mut delayText = self.delay.to_string();
let mut renderSkipText = self.renderSkip.to_string();
@ -123,38 +154,38 @@ impl GuiVec{
}
pub fn len(&self) -> usize{
fn len(&self) -> usize{
self.list.len()
}
pub async fn swap(&mut self, index1:usize, index2:usize) -> bool{
async fn swap(&mut self, index1:usize, index2:usize) -> bool{
self.writes += 2;
self.reads += 2;
self.list.swap(index1, index2);
self.draw().await;
self.done
}
pub fn randomize(&mut self){
fn randomize(&mut self){
self.list.shuffle();
}
pub fn elements(&mut self) -> std::slice::Iter<'_, Bar> {
fn elements(&mut self) -> std::slice::Iter<'_, Bar> {
self.list.iter()
}
pub fn get(&mut self, i:usize)-> &Bar{
fn get(&mut self, i:usize)-> &Bar{
self.reads += 1;
self.list.get(i).unwrap()
}
pub fn lessThan(&mut self, a:usize, b:usize) -> bool{
fn lessThan(&mut self, a:usize, b:usize) -> bool{
self.comps += 1;
return self.get(a).position < self.get(b).position
}
pub fn lessThanEqual(&mut self, a:usize, b:i32) -> bool{
fn lessThanEqual(&mut self, a:usize, b:i32) -> bool{
self.comps += 1;
return self.get(a).position <= b
}
pub fn isSorted(&mut self) -> bool{
fn isSorted(&mut self) -> bool{
self.reads += self.len() as i32;
let mut prev = 0;
for bar in self.list.iter() {
@ -166,7 +197,16 @@ impl GuiVec{
}
true
}
pub async fn show(&mut self){
async fn set(&mut self, i:usize, elem:Bar) -> bool{
self.writes += 1;
self.reads += 1;
self.list[i] = elem;
self.draw().await;
self.done
}
async fn show(&mut self){
loop{
if !self.done{
self.draw().await
@ -176,5 +216,81 @@ impl GuiVec{
}
}
fn getListClone(&self) -> Vec<Bar>{
self.list.clone()
}
}
struct NonGuiVec{
pub list: Vec<Bar>,
}
#[async_trait]
impl SortingList for NonGuiVec{
fn new(length:i32, 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))
}
NonGuiVec { list: list }
}
fn len(&self) -> usize{
self.list.len()
}
async fn swap(&mut self, index1:usize, index2:usize) -> bool{
self.list.swap(index1, index2);
false
}
async fn draw(&mut self){
self.swap(0, 0).await;
}
fn randomize(&mut self){
self.list.shuffle();
}
fn elements(&mut self) -> std::slice::Iter<'_, Bar> {
self.list.iter()
}
fn get(&mut self, i:usize)-> &Bar{
self.list.get(i).unwrap()
}
fn lessThan(&mut self, a:usize, b:usize) -> bool{
return self.get(a).position < self.get(b).position
}
fn lessThanEqual(&mut self, a:usize, b:i32) -> bool{
return self.get(a).position <= b
}
fn isSorted(&mut self) -> bool{
let mut prev = 0;
for bar in self.list.iter() {
if bar.position < prev{
return false;
}else{
prev = bar.position;
}
}
true
}
async fn set(&mut self, i:usize, elem:Bar) -> bool{
self.list[i] = elem;
self.draw().await;
false
}
async fn show(&mut self){
}
fn getListClone(&self) -> Vec<Bar>{
self.list.clone()
}
}

View file

@ -60,6 +60,9 @@ async fn main() {
if root_ui().button(Vec2::new(screen_width()*0.01, 250.), "Run QuickSort!"){
algo = "quickSort";
}
if root_ui().button(Vec2::new(screen_width()*0.01, 280.), "Run RadixSort!"){
algo = "radixSort";
}
if algo != ""{
Algorithm::Algorithm::run(length, 1.0, algo.to_string()).await;