tried to make bogosort on Rust + moved python ver

This commit is contained in:
2023-08-25 22:33:35 +03:00
parent 911d513829
commit 4030e4b01e
6 changed files with 356 additions and 3 deletions
+113
View File
@@ -0,0 +1,113 @@
import random
import datetime
import threading
import argparse
import locale
from string import Template
locale.setlocale(locale.LC_NUMERIC, ('en', 'UTF-8'))
parser = argparse.ArgumentParser(description='Sorting algorithm BogoSort is very simple: it just randomly shuffle values in array, until a miracle happens and the array is sorted')
parser.add_argument("array_size", metavar="N", type=int, help="Number or values in the array to sort")
parser.add_argument("-i", action='store_true', help="During sorting, information about the elapsed time, steps and sorting speed will not be displayed")
args = parser.parse_args()
def num4(num):
"""Number in 4 symbols and postfix (5 symbols)"""
num = int(num)
if len(str(num)) <= 4:
return str(num)
postfixs = ["k", "M", "B", "T", "q", "Q", "s", "S"]
nl = len(str(num))-1
scale = min(int(nl / 3), len(postfixs))
num /= 10**(3*scale)
decimal_length = 2 - nl % 3 if int(nl / 3) <= len(postfixs) else 0
return f"{num:.{decimal_length}f}{postfixs[scale-1]}"
class DeltaTemplate(Template):
delimiter = "%"
def strfdelta(dtfrom:datetime.datetime, zero:datetime.datetime) -> str:
if zero < dtfrom:
tdelta = dtfrom - zero
negative = True
else:
tdelta = zero - dtfrom
negative = False
show_days = True
if tdelta.days == 0: show_days = False
hours, rem = divmod(tdelta.seconds, 3600)
d = {"D": tdelta.days}
minutes, seconds = divmod(rem, 60)
if show_days:
d["H"] = '{:02d}'.format(hours)
d["M"] = '{:02d}'.format(minutes)
d["S"] = '{:02d}'.format(seconds)
if negative:
t = DeltaTemplate('- %D d. %H:%M:%S')
else:
t = DeltaTemplate('%D d. %H:%M:%S')
else:
hours += d["D"]*24
d["H"] = locale.format_string('%d', hours, grouping=True)
d["M"] = '{:02d}'.format(minutes)
d["S"] = '{:02d}'.format(seconds)
t = DeltaTemplate('-%H:%M:%S') if negative else DeltaTemplate('%H:%M:%S')
return t.substitute(**d)
class BogoSort:
def __init__(self):
self.step = 0
self.start_time = None
self.end_time = None
self.array = None
def sorting(self, l):
self.array = list(range(int(l)))
random.shuffle(self.array)
if int(l) > 100:
print(f"Array with {l} values created")
else:
print(f"Array created: {str(self.array)}")
self.start_time = datetime.datetime.now()
if args.i:
print(" [Ctrl+C чтобы прервать] Sorting...", end="\r")
else:
printing = threading.Thread(target=print_until_sorting, name=print_until_sorting, daemon=True)
printing.start()
try:
while any(x > y for x, y in zip(self.array, self.array[1:])):
x = random.randint(0, int(l)-1)
y = random.randint(0, int(l)-1)
self.array[x], self.array[y] = self.array[y], self.array[x]
self.step += 1
self.end_time = datetime.datetime.now()
done_str = "Done!" if int(l) > 100 else f"Done: {str(self.array)}"
print(done_str, end=" "*(90-len(done_str))+"\n")
self.stats()
except KeyboardInterrupt:
self.end_time = datetime.datetime.now()
print("Sorting interrupted by user", end=" "*80+"\n")
self.stats()
def stats(self):
bogosort_time = self.end_time - self.start_time
try:
steps_for_sec = locale.format_string("%.3f", self.step/bogosort_time.total_seconds(), grouping=True)
except Exception:
steps_for_sec = ""
print(f" {'Number of values:':25}{locale.format_string('%d', len(self.array), grouping=True)}")
print(f" {'Start time:':25}{self.start_time.strftime('%Y-%m-%d %H:%M:%S.%f')}")
print(f" {'Number of steps:':25}{locale.format_string('%d', self.step, grouping=True)}")
print(f" {'End time:':25}{self.end_time.strftime('%Y-%m-%d %H:%M:%S.%f')}")
print(f" {'Wasted time:':25}{bogosort_time}")
print(f" {'Sorting speed:':25}{steps_for_sec} step/sec")
sorting = BogoSort()
def print_until_sorting():
while sorting.end_time is None:
bogosort_time = datetime.datetime.now() - sorting.start_time
steps_for_sec = num4(sorting.step/bogosort_time.total_seconds()) if bogosort_time.total_seconds() > 1 else "---"
print(f" [Ctrl+C to interrupt] Sorting, {strfdelta(sorting.start_time, datetime.datetime.now())}, {num4(sorting.step)} steps, {steps_for_sec} step/sec", end=" "*5+"\r") # On case, if wanna see the exact value: locale.format_string('%d', sorting.step, grouping=True)
sorting.sorting(args.array_size)
+113
View File
@@ -0,0 +1,113 @@
import random
import datetime
import threading
import argparse
import locale
from string import Template
locale.setlocale(locale.LC_NUMERIC, ('ru_RU', 'UTF-8'))
parser = argparse.ArgumentParser(description='Алгоритм сортировки BogoSort очень прост: он просто передвигает значения в массиве в рандомные места, пока не случится чудо и массив не отсортируется')
parser.add_argument("array_size", metavar="N", type=int, help="Количество элементов в массиве для сортировки")
parser.add_argument("-i", action='store_true', help="Во время сортировки не будет выводится информация о потраченном времени, шагах и скорости сортировки")
args = parser.parse_args()
def num4(num):
"""Number in 4 symbols and postfix (5 symbols)"""
num = int(num)
if len(str(num)) <= 4:
return str(num)
postfixs = ["k", "M", "B", "T", "q", "Q", "s", "S"]
nl = len(str(num))-1
scale = min(int(nl / 3), len(postfixs))
num /= 10**(3*scale)
decimal_length = 2 - nl % 3 if int(nl / 3) <= len(postfixs) else 0
return f"{num:.{decimal_length}f}{postfixs[scale-1]}"
class DeltaTemplate(Template):
delimiter = "%"
def strfdelta(dtfrom:datetime.datetime, zero:datetime.datetime) -> str:
if zero < dtfrom:
tdelta = dtfrom - zero
negative = True
else:
tdelta = zero - dtfrom
negative = False
show_days = True
if tdelta.days == 0: show_days = False
hours, rem = divmod(tdelta.seconds, 3600)
d = {"D": tdelta.days}
minutes, seconds = divmod(rem, 60)
if show_days:
d["H"] = '{:02d}'.format(hours)
d["M"] = '{:02d}'.format(minutes)
d["S"] = '{:02d}'.format(seconds)
if negative:
t = DeltaTemplate('- %D дн. %H:%M:%S')
else:
t = DeltaTemplate('%D дн. %H:%M:%S')
else:
hours += d["D"]*24
d["H"] = locale.format_string('%d', hours, grouping=True)
d["M"] = '{:02d}'.format(minutes)
d["S"] = '{:02d}'.format(seconds)
t = DeltaTemplate('-%H:%M:%S') if negative else DeltaTemplate('%H:%M:%S')
return t.substitute(**d)
class BogoSort:
def __init__(self):
self.step = 0
self.start_time = None
self.end_time = None
self.array = None
def sorting(self, l):
self.array = list(range(int(l)))
random.shuffle(self.array)
if int(l) > 100:
print(f"Создан массив со {l} значениями")
else:
print(f"Создан массив: {str(self.array)}")
self.start_time = datetime.datetime.now()
if args.i:
print(" [Ctrl+C чтобы прервать] Сортировка...", end="\r")
else:
printing = threading.Thread(target=print_until_sorting, name=print_until_sorting, daemon=True)
printing.start()
try:
while any(x > y for x, y in zip(self.array, self.array[1:])):
x = random.randint(0, int(l)-1)
y = random.randint(0, int(l)-1)
self.array[x], self.array[y] = self.array[y], self.array[x]
self.step += 1
self.end_time = datetime.datetime.now()
done_str = "Готово!" if int(l) > 100 else f"Готово: {str(self.array)}"
print(done_str, end=" "*(90-len(done_str))+"\n")
self.stats()
except KeyboardInterrupt:
self.end_time = datetime.datetime.now()
print("Сортировка прервана пользователем", end=" "*80+"\n")
self.stats()
def stats(self):
bogosort_time = self.end_time - self.start_time
try:
steps_for_sec = locale.format_string("%.3f", self.step/bogosort_time.total_seconds(), grouping=True)
except Exception:
steps_for_sec = ""
print(f" {'Кол-во элементов:':25}{locale.format_string('%d', len(self.array), grouping=True)}")
print(f" {'Время старта:':25}{self.start_time.strftime('%d.%m.%Y %H:%M:%S.%f')}")
print(f" {'Кол-во шагов:':25}{locale.format_string('%d', self.step, grouping=True)}")
print(f" {'Время завершения:':25}{self.end_time.strftime('%d.%m.%Y %H:%M:%S.%f')}")
print(f" {'Потрачено времени:':25}{bogosort_time}")
print(f" {'Скорость сортировки:':25}{steps_for_sec} шаг/сек")
sorting = BogoSort()
def print_until_sorting():
while sorting.end_time is None:
bogosort_time = datetime.datetime.now() - sorting.start_time
steps_for_sec = num4(sorting.step/bogosort_time.total_seconds()) if bogosort_time.total_seconds() > 1 else "---"
print(f" [Ctrl+C чтобы прервать] Сортировка, {strfdelta(sorting.start_time, datetime.datetime.now())}, {num4(sorting.step)} шагов, {steps_for_sec} шаг/сек", end=" "*5+"\r") # На случай, если захочется видеть точную цифру: locale.format_string('%d', sorting.step, grouping=True)
sorting.sorting(args.array_size)
-3
View File
@@ -1,7 +1,4 @@
# GitHub аккаунт самого унылого разраба
Репозиторий, из которого берётся этот README, является моей личной свалкой, в которой валяется всякая хрень.
[![Anurag's github stats](https://github-readme-stats.vercel.app/api?username=dan63047&include_all_commits=True&custom_title=Моя%20стата&show_icons=true&theme=dark)](https://github.com/anuraghazra/github-readme-stats)
[Ссылочки на меня в сети](https://dan63.by)
+75
View File
@@ -0,0 +1,75 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "bogosort"
version = "0.1.0"
dependencies = [
"rand",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "getrandom"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "libc"
version = "0.2.147"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
[[package]]
name = "ppv-lite86"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom",
]
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+9
View File
@@ -0,0 +1,9 @@
[package]
name = "bogosort"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
rand = "0.8.5"
+46
View File
@@ -0,0 +1,46 @@
use rand::Rng;
use rand::thread_rng;
use rand::seq::SliceRandom;
//use std::thread;
use std::time::Instant;
fn is_sorted<T>(data: &[T]) -> bool
where
T: Ord,
{
data.windows(2).all(|w| w[0] <= w[1])
}
fn main() {
println!("Enter array length:");
let mut input = String::new();
let mut steps: u128 = 0;
std::io::stdin().read_line(&mut input).expect("Failed to read line");
let n: usize = match input.trim().parse() {
Ok(num) => num,
Err(_) => panic!("crash and burn"),
};
let mut array : Vec<u32> = (1..=n as u32).collect();
array.shuffle(&mut thread_rng());
println!("Array created: {:?}", &array);
let now = Instant::now();
// thread::spawn(|| {
// while !is_sorted(&array) {
// print!("{:?} {}\r", &array, &steps);
// }
// });
while !is_sorted(&array) {
let x = thread_rng().gen_range(0..=n-1);
let y = thread_rng().gen_range(0..=n-1);
let z = array[x];
array[x] = array[y];
array[y] = z;
steps += 1;
}
let elapsed_time = now.elapsed();
let elapsed_secs: f64 = elapsed_time.as_nanos() as f64/1_000_000_000.0;
println!("Done: {:?}\nSteps: {}\nEslaped: {:?}\nSpeed: {} steps/second", &array, &steps, &elapsed_time, steps as f64/&elapsed_secs);
}
// TODO: print info while in process
// TODO: print stats after ^C