WIP
This commit is contained in:
parent
8928401233
commit
ccaf8c1f0b
11 changed files with 611 additions and 39 deletions
53
src/algorithm/binaryHeap.rs
Normal file
53
src/algorithm/binaryHeap.rs
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
|
||||||
|
use crate::drawableVec::DrawableVec;
|
||||||
|
|
||||||
|
use std::collections::{HashMap, BinaryHeap};
|
||||||
|
|
||||||
|
use color_eyre::Result;
|
||||||
|
|
||||||
|
pub async fn sort(list: &mut DrawableVec) -> Result<()>{
|
||||||
|
|
||||||
|
let mut indexMap:HashMap<u32, usize> = HashMap::new();
|
||||||
|
let mut binHeap:BinaryHeap<u32> = BinaryHeap::new();
|
||||||
|
|
||||||
|
let mut ind = 0;
|
||||||
|
for bar in list.elements(){
|
||||||
|
binHeap.push(*bar);
|
||||||
|
indexMap.insert(*bar, ind);
|
||||||
|
ind += 1;
|
||||||
|
}
|
||||||
|
for i in (0..list.len()).rev(){
|
||||||
|
let bar = binHeap.pop().unwrap();
|
||||||
|
let barIndex = *indexMap.get(&bar).unwrap();
|
||||||
|
list.swap(i, barIndex).await?;
|
||||||
|
let temp = list.get(barIndex);
|
||||||
|
indexMap.insert(temp, barIndex);
|
||||||
|
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
mod tests {
|
||||||
|
use crate::GuiHookVec::NonGuiVec;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
|
||||||
|
macro_rules! aw {
|
||||||
|
($e:expr) => {
|
||||||
|
tokio_test::block_on($e)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn binartHeap_correct() {
|
||||||
|
let mut list:NonGuiVec = aw!(SortingList::new(1000,0.0));
|
||||||
|
aw!(binaryHeap(&mut list));
|
||||||
|
assert_eq!( list.isSorted(), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
40
src/algorithm/bogoSort.rs
Normal file
40
src/algorithm/bogoSort.rs
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
use crate::drawableVec::DrawableVec;
|
||||||
|
|
||||||
|
use color_eyre::Result;
|
||||||
|
pub async fn sort(list: &mut DrawableVec) -> Result<()>{
|
||||||
|
|
||||||
|
loop{
|
||||||
|
list.swap(0,0).await?;
|
||||||
|
if list.isSorted() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
list.randomize();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
mod tests {
|
||||||
|
use crate::GuiHookVec::NonGuiVec;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
|
||||||
|
macro_rules! aw {
|
||||||
|
($e:expr) => {
|
||||||
|
tokio_test::block_on($e)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn bogoSort_correct_this_is_a_meme() {
|
||||||
|
let mut list:NonGuiVec = aw!(SortingList::new(5,0.0));
|
||||||
|
aw!(bogoSort(&mut list));
|
||||||
|
assert_eq!( list.isSorted(), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
41
src/algorithm/bubbleSort.rs
Normal file
41
src/algorithm/bubbleSort.rs
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
use crate::drawableVec::DrawableVec;
|
||||||
|
|
||||||
|
use color_eyre::Result;
|
||||||
|
|
||||||
|
pub async fn sort(list:&mut DrawableVec) -> Result<()>{
|
||||||
|
let n = list.len();
|
||||||
|
for i in 0..n {
|
||||||
|
for j in 0..(n - i - 1) {
|
||||||
|
if list.lessThan(j + 1, j) {
|
||||||
|
list.swap(j, j + 1).await?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
#[cfg(test)]
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
mod tests {
|
||||||
|
use crate::GuiHookVec::NonGuiVec;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
|
||||||
|
macro_rules! aw {
|
||||||
|
($e:expr) => {
|
||||||
|
tokio_test::block_on($e)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn bubblesort_correct() {
|
||||||
|
let mut list:NonGuiVec = aw!(SortingList::new(1000,0.0));
|
||||||
|
aw!(bubbleSort(&mut list));
|
||||||
|
assert_eq!( list.isSorted(), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
58
src/algorithm/coctailShaker.rs
Normal file
58
src/algorithm/coctailShaker.rs
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
use crate::drawableVec::DrawableVec;
|
||||||
|
|
||||||
|
use color_eyre::Result;
|
||||||
|
|
||||||
|
pub async fn sort(list:&mut DrawableVec) -> Result<()>{
|
||||||
|
let mut lowerBound = 0;
|
||||||
|
let mut upperBound = list.len()-1;
|
||||||
|
let mut swapped = true;
|
||||||
|
while swapped{
|
||||||
|
swapped = false;
|
||||||
|
for i in lowerBound..upperBound {
|
||||||
|
if list.lessThan(i+1, i) {
|
||||||
|
list.swap(i, i+1).await?;
|
||||||
|
swapped = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !swapped{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
swapped = false;
|
||||||
|
upperBound = upperBound-1;
|
||||||
|
for i in ((lowerBound)..(upperBound)).rev() {
|
||||||
|
if list.lessThan(i+1, i) {
|
||||||
|
list.swap(i+1, i).await?;
|
||||||
|
swapped = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lowerBound = lowerBound+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
#[cfg(test)]
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
mod tests {
|
||||||
|
use crate::GuiHookVec::NonGuiVec;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
|
||||||
|
macro_rules! aw {
|
||||||
|
($e:expr) => {
|
||||||
|
tokio_test::block_on($e)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn coctailshakersort_correct() {
|
||||||
|
let mut list:NonGuiVec = aw!(SortingList::new(1000,0.0));
|
||||||
|
aw!(cocktailShaker(&mut list));
|
||||||
|
assert_eq!( list.isSorted(), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
|
@ -1,3 +1,29 @@
|
||||||
use crate::drawableVec::DrawableVec;
|
use crate::drawableVec::DrawableVec;
|
||||||
|
|
||||||
pub mod insertSort;
|
mod radixSort;
|
||||||
|
mod insertSort;
|
||||||
|
mod bubbleSort;
|
||||||
|
mod binaryHeap;
|
||||||
|
mod coctailShaker;
|
||||||
|
mod quickSort;
|
||||||
|
mod bogoSort;
|
||||||
|
mod radixSortLSD;
|
||||||
|
use color_eyre::{eyre::Ok, Result};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
pub async fn sort(algo: String, list: &mut DrawableVec) -> Result<()> {
|
||||||
|
match algo.as_str() {
|
||||||
|
"insertSort" => insertSort::sort(list).await?,
|
||||||
|
"bubbleSort" => bubbleSort::sort(list).await?,
|
||||||
|
"bogoSort" => bogoSort::sort(list).await?,
|
||||||
|
"cocktailShaker" => coctailShaker::sort(list).await?,
|
||||||
|
"binaryHeap" => binaryHeap::sort(list).await?,
|
||||||
|
"quickSort" => quickSort::sort(list).await?,
|
||||||
|
"radixSortMSD" => radixSort::sort(list).await?,
|
||||||
|
"radixSortLSD" => radixSortLSD::sort(list).await?,
|
||||||
|
_ => panic!("No algorithm with that name implemented!")
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
74
src/algorithm/quickSort.rs
Normal file
74
src/algorithm/quickSort.rs
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
use crate::drawableVec::DrawableVec;
|
||||||
|
|
||||||
|
use color_eyre::Result;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
pub async fn sort(list:&mut DrawableVec) -> Result<()> {
|
||||||
|
let mut stack:Vec<(usize,usize)> = Vec::new();
|
||||||
|
|
||||||
|
let start = 0;
|
||||||
|
let end = list.len()-1;
|
||||||
|
|
||||||
|
stack.push((start,end));
|
||||||
|
|
||||||
|
while stack.len() > 0{
|
||||||
|
let (start,end) = stack.pop().unwrap();
|
||||||
|
|
||||||
|
let p = list.get(end);
|
||||||
|
let temp = partition(list, start, end, p).await?;
|
||||||
|
let pivot = if temp >= 0 {temp} else {break;};
|
||||||
|
|
||||||
|
if pivot != 0 && pivot as usize -1 > start{
|
||||||
|
|
||||||
|
stack.push((start,pivot as usize-1));
|
||||||
|
}
|
||||||
|
|
||||||
|
if pivot as usize + 1 < end{
|
||||||
|
stack.push((pivot as usize +1, end))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async fn partition(list:&mut DrawableVec, low:usize, high:usize, p:u32) -> Result<i32>{
|
||||||
|
let mut pIndex = low;
|
||||||
|
|
||||||
|
for i in low..high{
|
||||||
|
if list.lessThanEqual(i, p){
|
||||||
|
list.swap(i, pIndex).await?;
|
||||||
|
pIndex += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
list.swap(pIndex, high).await?;
|
||||||
|
|
||||||
|
return Ok(pIndex as i32)
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
#[cfg(test)]
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
mod tests {
|
||||||
|
use crate::GuiHookVec::NonGuiVec;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
|
||||||
|
macro_rules! aw {
|
||||||
|
($e:expr) => {
|
||||||
|
tokio_test::block_on($e)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn quicksort_correct() {
|
||||||
|
let mut list:NonGuiVec = aw!(SortingList::new(1000,0.0));
|
||||||
|
aw!(quickSort(&mut list));
|
||||||
|
assert_eq!( list.isSorted(), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
124
src/algorithm/radixSort.rs
Normal file
124
src/algorithm/radixSort.rs
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
use crate::drawableVec::DrawableVec;
|
||||||
|
|
||||||
|
use color_eyre::{eyre::Ok, Result};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
pub async fn sort(list:&mut DrawableVec) -> Result<()> {
|
||||||
|
|
||||||
|
let mut max = usize::MIN;
|
||||||
|
for i in list.getListClone().into_iter().map(|x| format!("{:b}",x)){
|
||||||
|
|
||||||
|
if max < i.len(){
|
||||||
|
max = i.len();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
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 Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
stack = stack2.clone();
|
||||||
|
stack2.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn radix(list:&mut DrawableVec, radix:usize, mut minBoundry:usize, mut maxBoundry:usize) -> Result<Option<(usize,usize,usize)>>{
|
||||||
|
let initialMin = minBoundry.clone();
|
||||||
|
let initialMax = maxBoundry.clone();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
loop{
|
||||||
|
if maxBoundry == minBoundry{
|
||||||
|
break
|
||||||
|
}
|
||||||
|
let currentBit = get_bit_at(list.get(minBoundry), radix);
|
||||||
|
|
||||||
|
if currentBit{
|
||||||
|
list.swap(minBoundry, maxBoundry-1).await?;
|
||||||
|
maxBoundry -= 1;
|
||||||
|
}else{
|
||||||
|
list.swap(minBoundry, minBoundry).await?;
|
||||||
|
|
||||||
|
minBoundry += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Ok(Some((initialMin, minBoundry, initialMax)))
|
||||||
|
}
|
||||||
|
fn get_bit_at(input: u32, n: usize) -> bool {
|
||||||
|
|
||||||
|
if format!("{:b}", input).len() <= n{
|
||||||
|
false
|
||||||
|
}else{
|
||||||
|
input & (1 << n) != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
#[cfg(test)]
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
mod tests {
|
||||||
|
use crate::GuiHookVec::NonGuiVec;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
|
||||||
|
macro_rules! aw {
|
||||||
|
($e:expr) => {
|
||||||
|
tokio_test::block_on($e)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn radixsort_correct() {
|
||||||
|
let mut list:NonGuiVec = aw!(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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
100
src/algorithm/radixSortLSD.rs
Normal file
100
src/algorithm/radixSortLSD.rs
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
use crate::drawableVec::DrawableVec;
|
||||||
|
|
||||||
|
use color_eyre::Result;
|
||||||
|
|
||||||
|
pub async fn sort(list:&mut DrawableVec) -> Result<()> {
|
||||||
|
|
||||||
|
let mut max = usize::MIN;
|
||||||
|
for i in list.getListClone().into_iter().map(|x| format!("{:b}",x)){
|
||||||
|
|
||||||
|
if max < i.len(){
|
||||||
|
max = i.len();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
for i in 0..(max){
|
||||||
|
radix(list, i).await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn radix(list:&mut DrawableVec, radix:usize) -> Result<()>{
|
||||||
|
let mut bucket = vec![vec![];2];
|
||||||
|
|
||||||
|
for (i, bar) in list.elements().enumerate(){
|
||||||
|
|
||||||
|
let cur = if get_bit_at(*bar, radix) {1} else {0};
|
||||||
|
|
||||||
|
bucket[cur].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(){
|
||||||
|
list.set(count, listClone[i]).await?;
|
||||||
|
count += 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_bit_at(input: u32, n: usize) -> bool {
|
||||||
|
|
||||||
|
if format!("{:b}", input).len() <= n{
|
||||||
|
false
|
||||||
|
}else{
|
||||||
|
input & (1 << n) != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
mod tests {
|
||||||
|
use crate::GuiHookVec::NonGuiVec;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
|
||||||
|
macro_rules! aw {
|
||||||
|
($e:expr) => {
|
||||||
|
tokio_test::block_on($e)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn radixsort_correct() {
|
||||||
|
let mut list:NonGuiVec = aw!(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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
|
@ -1,6 +1,7 @@
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use color_eyre::{eyre::Ok, Result};
|
use color_eyre::{eyre::Ok, Result};
|
||||||
|
use rand::seq::SliceRandom;
|
||||||
use ratatui::{
|
use ratatui::{
|
||||||
DefaultTerminal, Frame,
|
DefaultTerminal, Frame,
|
||||||
crossterm::event::{self, Event, KeyCode, KeyEventKind},
|
crossterm::event::{self, Event, KeyCode, KeyEventKind},
|
||||||
|
@ -12,8 +13,8 @@ use ratatui::{
|
||||||
use tokio::{sync::mpsc::{UnboundedReceiver, UnboundedSender}, time::sleep};
|
use tokio::{sync::mpsc::{UnboundedReceiver, UnboundedSender}, time::sleep};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
algorithm::{self, insertSort::{self, sort}},
|
algorithm::{self},
|
||||||
graphics::{self, vertical_barchart}, tui::{self, Message},
|
tui::Message,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub enum SortingMessage{
|
pub enum SortingMessage{
|
||||||
|
@ -23,7 +24,8 @@ pub enum SortingMessage{
|
||||||
pub struct DrawableVec {
|
pub struct DrawableVec {
|
||||||
vec: Vec<u32>,
|
vec: Vec<u32>,
|
||||||
event_rx: UnboundedReceiver<SortingMessage>,
|
event_rx: UnboundedReceiver<SortingMessage>,
|
||||||
event_tx: UnboundedSender<Message>
|
event_tx: UnboundedSender<Message>,
|
||||||
|
algo: String
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DrawableVec {
|
impl DrawableVec {
|
||||||
|
@ -31,12 +33,13 @@ impl DrawableVec {
|
||||||
return DrawableVec {
|
return DrawableVec {
|
||||||
vec,
|
vec,
|
||||||
event_rx,
|
event_rx,
|
||||||
event_tx: event_tx.clone()
|
event_tx: event_tx.clone(),
|
||||||
|
algo: "radixSortMSD".to_string(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn run(mut self) -> Result<()> {
|
pub async fn run(mut self) -> Result<()> {
|
||||||
insertSort::sort(&mut self).await?;
|
algorithm::sort(self.algo.clone(), &mut self).await?;
|
||||||
sleep(Duration::from_secs(100000)).await;
|
sleep(Duration::from_secs(100000)).await;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -53,7 +56,47 @@ impl DrawableVec {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn set(&mut self, i:usize, elem:u32) -> Result<()>{
|
||||||
|
self.vec[i] = elem;
|
||||||
|
self.event_tx.send(Message::SetEvent(i, elem))?;
|
||||||
|
|
||||||
|
self.event_rx.recv().await;
|
||||||
|
Ok(())
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
pub fn lessThan(&self, a: usize, b: usize) -> bool {
|
pub fn lessThan(&self, a: usize, b: usize) -> bool {
|
||||||
self.vec[a] < self.vec[b]
|
self.vec[a] < self.vec[b]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn elements(&mut self) -> std::slice::Iter<'_, u32> {
|
||||||
|
self.vec.iter()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get(&mut self, i:usize)-> u32{
|
||||||
|
*self.vec.get(i).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn randomize(&mut self){
|
||||||
|
self.vec.shuffle(&mut rand::rng());
|
||||||
|
}
|
||||||
|
pub fn isSorted(&mut self) -> bool{
|
||||||
|
let mut prev:u32 = 0;
|
||||||
|
for bar in self.elements() {
|
||||||
|
if *bar < prev{
|
||||||
|
return false;
|
||||||
|
}else{
|
||||||
|
prev = *bar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn lessThanEqual(&mut self, a:usize, b:u32) -> bool{
|
||||||
|
return self.get(a) <= b
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getListClone(&self) -> Vec<u32>{
|
||||||
|
self.vec.clone()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,11 +13,9 @@ pub fn vertical_barchart(temperatures: &[u32]) -> BarChart {
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(hour, value)| vertical_bar(hour, value))
|
.map(|(hour, value)| vertical_bar(hour, value))
|
||||||
.collect();
|
.collect();
|
||||||
let title = Line::from("Weather (Vertical)").centered();
|
|
||||||
BarChart::default()
|
BarChart::default()
|
||||||
.data(BarGroup::default().bars(&bars))
|
.data(BarGroup::default().bars(&bars))
|
||||||
.block(Block::new().title(title))
|
.bar_width(1)
|
||||||
.bar_width(5)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn vertical_bar(hour: usize, temperature: &u32) -> Bar {
|
pub fn vertical_bar(hour: usize, temperature: &u32) -> Bar {
|
||||||
|
|
49
src/tui.rs
49
src/tui.rs
|
@ -1,16 +1,26 @@
|
||||||
use std::{time::Duration};
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use color_eyre::{Result, eyre::Ok};
|
||||||
use crossterm::event::{Event, KeyCode, KeyEventKind, MouseEventKind};
|
use crossterm::event::{Event, KeyCode, KeyEventKind, MouseEventKind};
|
||||||
use rand::seq::SliceRandom;
|
use rand::seq::SliceRandom;
|
||||||
use ratatui::{layout::{Constraint, Layout}, prelude::CrosstermBackend, style::Stylize, Terminal};
|
use ratatui::{
|
||||||
use tokio::{sync::mpsc::{self, UnboundedReceiver, UnboundedSender}, task::JoinHandle, time};
|
Terminal,
|
||||||
use color_eyre::{eyre::Ok, Result};
|
layout::{Constraint, Layout},
|
||||||
|
prelude::CrosstermBackend,
|
||||||
|
style::Stylize,
|
||||||
|
};
|
||||||
|
use tokio::{
|
||||||
|
sync::mpsc::{self, UnboundedReceiver, UnboundedSender},
|
||||||
|
task::JoinHandle,
|
||||||
|
time,
|
||||||
|
};
|
||||||
pub enum Message {
|
pub enum Message {
|
||||||
Quit,
|
Quit,
|
||||||
Tick,
|
Tick,
|
||||||
Render,
|
Render,
|
||||||
StartSimulation,
|
StartSimulation,
|
||||||
SwapEvent(usize, usize)
|
SwapEvent(usize, usize),
|
||||||
|
SetEvent(usize, u32),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Tui {
|
pub struct Tui {
|
||||||
|
@ -23,8 +33,10 @@ pub struct Tui{
|
||||||
should_exit: bool,
|
should_exit: bool,
|
||||||
vec: Vec<u32>,
|
vec: Vec<u32>,
|
||||||
}
|
}
|
||||||
use crate::{drawableVec::{self, DrawableVec, SortingMessage}, graphics::vertical_barchart};
|
use crate::{
|
||||||
|
drawableVec::{self, DrawableVec, SortingMessage},
|
||||||
|
graphics::vertical_barchart,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum UpdateCommand {
|
pub enum UpdateCommand {
|
||||||
|
@ -35,7 +47,8 @@ pub enum UpdateCommand {
|
||||||
impl Tui {
|
impl Tui {
|
||||||
pub fn new() -> Result<Self> {
|
pub fn new() -> Result<Self> {
|
||||||
let terminal = ratatui::init();
|
let terminal = ratatui::init();
|
||||||
let (event_tx, event_rx):(UnboundedSender<Message>,UnboundedReceiver<Message>) = mpsc::unbounded_channel();
|
let (event_tx, event_rx): (UnboundedSender<Message>, UnboundedReceiver<Message>) =
|
||||||
|
mpsc::unbounded_channel();
|
||||||
let (sorting_tx, sorting_rx) = mpsc::unbounded_channel();
|
let (sorting_tx, sorting_rx) = mpsc::unbounded_channel();
|
||||||
let mut vec = (Vec::from_iter(1..100));
|
let mut vec = (Vec::from_iter(1..100));
|
||||||
vec.shuffle(&mut rand::rng());
|
vec.shuffle(&mut rand::rng());
|
||||||
|
@ -43,11 +56,10 @@ impl Tui{
|
||||||
|
|
||||||
let sorter = tokio::spawn(drawableVec.run());
|
let sorter = tokio::spawn(drawableVec.run());
|
||||||
|
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
terminal,
|
terminal,
|
||||||
tick_rate: 10.,
|
tick_rate: 20.,
|
||||||
frame_rate: 60.,
|
frame_rate: 120.,
|
||||||
event_rx,
|
event_rx,
|
||||||
event_tx,
|
event_tx,
|
||||||
sorting_tx,
|
sorting_tx,
|
||||||
|
@ -96,18 +108,22 @@ impl Tui{
|
||||||
async fn update(&mut self, message: Message) -> Result<UpdateCommand> {
|
async fn update(&mut self, message: Message) -> Result<UpdateCommand> {
|
||||||
match message {
|
match message {
|
||||||
Message::Quit => Ok(UpdateCommand::Quit),
|
Message::Quit => Ok(UpdateCommand::Quit),
|
||||||
Message::Tick => {
|
Message::Tick => Ok(UpdateCommand::None),
|
||||||
Ok(UpdateCommand::None)
|
|
||||||
}
|
|
||||||
Message::Render => {
|
Message::Render => {
|
||||||
self.view()?;
|
self.view()?;
|
||||||
Ok(UpdateCommand::None)
|
Ok(UpdateCommand::None)
|
||||||
}
|
}
|
||||||
Message::StartSimulation => todo!(),
|
Message::StartSimulation => todo!(),
|
||||||
Message::SwapEvent(a,b) => {self.vec.swap(a, b); Ok(UpdateCommand::None)},
|
Message::SwapEvent(a, b) => {
|
||||||
|
self.vec.swap(a, b);
|
||||||
|
Ok(UpdateCommand::None)
|
||||||
|
}
|
||||||
|
Message::SetEvent(i, e) => {
|
||||||
|
self.vec.insert(i, e);
|
||||||
|
Ok(UpdateCommand::None)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn view(&mut self) -> Result<()> {
|
fn view(&mut self) -> Result<()> {
|
||||||
self.terminal.draw(|frame| {
|
self.terminal.draw(|frame| {
|
||||||
|
@ -138,5 +154,4 @@ impl Tui{
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in a new issue