tried to make bogosort on Rust + moved python ver
This commit is contained in:
@@ -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)
|
||||
@@ -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)
|
||||
@@ -1,7 +1,4 @@
|
||||
# GitHub аккаунт самого унылого разраба
|
||||
Репозиторий, из которого берётся этот README, является моей личной свалкой, в которой валяется всякая хрень.
|
||||
|
||||
[](https://github.com/anuraghazra/github-readme-stats)
|
||||
|
||||
[Ссылочки на меня в сети](https://dan63.by)
|
||||
|
||||
|
||||
Generated
+75
@@ -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"
|
||||
@@ -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"
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user