Advertisement
Amorf

Untitled

Oct 7th, 2021
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.21 KB | None | 0 0
  1. import random
  2. import datetime
  3. import threading
  4. import argparse
  5. import locale
  6. from string import Template
  7.  
  8. False
  9.  
  10. locale.setlocale(locale.LC_NUMERIC, ('ru_RU', 'UTF-8'))
  11. parser = argparse.ArgumentParser(description='Алгоритм сортировки BogoSort очень прост: он просто передвигает значения в массиве в рандомные места, пока не случится чудо и массив не отсортируется')
  12. parser.add_argument("array_size", metavar="N", type=int, help="Количество элементов в массиве для сортировки")
  13. parser.add_argument("-i", action='store_true', help="Во время сортировки не будет выводится информация о потраченном времени, шагах и скорости сортировки")
  14. args = parser.parse_args()
  15.  
  16. def num4(num):
  17.     """Number in 4 symbols and postfix (5 symbols)"""
  18.     num = int(num)
  19.     if len(str(num)) <= 4:
  20.         return str(num)
  21.     postfixs = ["k", "M", "B", "T", "q", "Q", "s", "S"]
  22.     nl = len(str(num))-1
  23.     scale = min(int(nl / 3), len(postfixs))
  24.     num /= 10**(3*scale)
  25.     decimal_length = 2 - nl % 3 if int(nl / 3) <= len(postfixs) else 0
  26.     return f"{num:.{decimal_length}f}{postfixs[scale-1]}"
  27.  
  28. class DeltaTemplate(Template):
  29.     delimiter = "%"
  30.  
  31. def strfdelta(dtfrom:datetime.datetime, zero:datetime.datetime) -> str:
  32.     if zero < dtfrom:
  33.         tdelta = dtfrom - zero
  34.         negative = True
  35.     else:
  36.         tdelta = zero - dtfrom
  37.         negative = False
  38.     show_days = True
  39.     if tdelta.days == 0: show_days = False
  40.     hours, rem = divmod(tdelta.seconds, 3600)
  41.     d = {"D": tdelta.days}
  42.     minutes, seconds = divmod(rem, 60)
  43.     if show_days:
  44.         d["H"] = '{:02d}'.format(hours)
  45.         d["M"] = '{:02d}'.format(minutes)
  46.         d["S"] = '{:02d}'.format(seconds)
  47.         if negative:
  48.             t = DeltaTemplate('- %D дн. %H:%M:%S')
  49.         else:
  50.             t = DeltaTemplate('%D дн. %H:%M:%S')
  51.     else:
  52.         hours += d["D"]*24
  53.         d["H"] = locale.format_string('%d', hours, grouping=True)
  54.         d["M"] = '{:02d}'.format(minutes)
  55.         d["S"] = '{:02d}'.format(seconds)
  56.         t = DeltaTemplate('-%H:%M:%S') if negative else DeltaTemplate('%H:%M:%S')
  57.  
  58.     return t.substitute(**d)
  59.  
  60. class BogoSort:
  61.     def __init__(self):
  62.         self.step = 0
  63.         self.start_time = None
  64.         self.end_time = None
  65.         self.array = None
  66.  
  67.     def sorting(self, l):
  68.         self.array = list(range(int(l)))
  69.         random.shuffle(self.array)
  70.         if int(l) > 100:
  71.             print(f"Создан массив со {l} значениями")
  72.         else:
  73.             print(f"Создан массив: {str(self.array)}")
  74.         self.start_time = datetime.datetime.now()
  75.         if args.i:
  76.             print(" [Ctrl+C чтобы прервать] Сортировка...", end="\r")
  77.         else:
  78.             printing = threading.Thread(target=print_until_sorting, name=print_until_sorting, daemon=True)
  79.             printing.start()
  80.         try:
  81.             while any(x > y for x, y in zip(self.array, self.array[1:])):
  82.                 x = random.randint(0, int(l)-1)
  83.                 y = random.randint(0, int(l)-1)
  84.                 self.array[x], self.array[y] = self.array[y], self.array[x]
  85.                 self.step += 1
  86.             self.end_time = datetime.datetime.now()
  87.             done_str = "Готово!" if int(l) > 100 else f"Готово: {str(self.array)}"
  88.             print(done_str, end=" "*(90-len(done_str))+"\n")
  89.             self.stats()
  90.         except KeyboardInterrupt:
  91.             self.end_time = datetime.datetime.now()
  92.             print("Сортировка прервана пользователем", end=" "*80+"\n")
  93.             self.stats()
  94.  
  95.     def stats(self):
  96.         bogosort_time = self.end_time - self.start_time
  97.         try:
  98.             steps_for_sec = locale.format_string("%.3f", self.step/bogosort_time.total_seconds(), grouping=True)
  99.         except Exception:
  100.             steps_for_sec = "∞"
  101.         print(f" {'Кол-во элементов:':25}{locale.format_string('%d', len(self.array), grouping=True)}")
  102.         print(f" {'Время старта:':25}{self.start_time.strftime('%d.%m.%Y %H:%M:%S.%f')}")
  103.         print(f" {'Кол-во шагов:':25}{locale.format_string('%d', self.step, grouping=True)}")
  104.         print(f" {'Время завершения:':25}{self.end_time.strftime('%d.%m.%Y %H:%M:%S.%f')}")
  105.         print(f" {'Потрачено времени:':25}{bogosort_time}")
  106.         print(f" {'Скорость сортировки:':25}{steps_for_sec} шаг/сек")
  107.  
  108.  
  109. sorting = BogoSort()
  110. def print_until_sorting():
  111.     while sorting.end_time is None:
  112.         bogosort_time = datetime.datetime.now() - sorting.start_time
  113.         steps_for_sec = num4(sorting.step/bogosort_time.total_seconds()) if bogosort_time.total_seconds() > 1 else "---"
  114.         print(f" [Ctrl+C чтобы прервать] Сортировка, {strfdelta(sorting.start_time, datetime.datetime.now())}, {num4(sorting.step)} шагов, {steps_for_sec} шаг/сек", end="  "*5+"\r")
  115. sorting.sorting(args.array_size)
  116.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement