diff --git a/task_1.py b/task_1.py new file mode 100644 index 00000000..c67b488f --- /dev/null +++ b/task_1.py @@ -0,0 +1,61 @@ +""" +1. Отсортируйте по убыванию методом "пузырька" одномерный целочисленный массив, +заданный случайными числами на промежутке [-100; 100). Выведите на экран +исходный и отсортированный массивы. Сортировка должна быть реализована в +виде функции. Обязательно доработайте алгоритм (сделайте его умнее). + +Идея доработки: если за проход по списку не совершается ни одной сортировки, +то завершение +Обязательно сделайте замеры времени обеих реализаций +и обосновать дала ли оптимизация эффективность + +Подсказка: обратите внимание, сортируем не по возрастанию, как в примере, +а по убыванию +""" +"""Сортировка пузырьком""" + +import timeit + +# исходный массив +orig_list = [71, -7, 97, -51, -76, -39, -41, -77, -21, -30, -97, -9, 12, 92, -47, 33, 79, 70, -90, -79] +def b_sort_desc(lst_obj): + n = 1 + while n < len(lst_obj): + for i in range(len(lst_obj)-n): + if lst_obj[i] < lst_obj[i+1]: + lst_obj[i], lst_obj[i+1] = lst_obj[i+1], lst_obj[i] + n += 1 + return lst_obj + + +# тот же массив, но последние 10 элементов уже отсортированы +orig_list_presorted = [71, -7, 97, -21, -9, 12, 92, 33, 79, 70, -30, -39, -41,-47, -51, -76, -77, -79, -90, -97] +def b_sort_desc_v2(lst_obj): + n = 1 + while n < len(lst_obj): + is_sorted = False + for i in range(len(lst_obj)-n): + if lst_obj[i] < lst_obj[i+1]: + lst_obj[i], lst_obj[i+1] = lst_obj[i+1], lst_obj[i] + is_sorted = True + if not is_sorted: + break + n += 1 + return lst_obj + +print(f'Source list\n {orig_list}') +print(f'With no optimization\n {b_sort_desc(orig_list)}') +print(f'Source list partly presorted\n {orig_list_presorted}') +print(f'With optimization\n {b_sort_desc_v2(orig_list_presorted)}') + + +print(timeit.timeit("b_sort_desc(orig_list)", \ + setup="from __main__ import b_sort_desc, orig_list", number=100)) + +print(timeit.timeit("b_sort_desc_v2(orig_list_presorted)", \ + setup="from __main__ import b_sort_desc_v2, orig_list_presorted", number=100)) + +""" +Без оптимизации 0.0019780999999999965 +С оптимизацией 0.00015790000000000248 +""" \ No newline at end of file diff --git a/task_2.py b/task_2.py new file mode 100644 index 00000000..ee3b8166 --- /dev/null +++ b/task_2.py @@ -0,0 +1,51 @@ +""" +2. Отсортируйте по возрастанию методом слияния одномерный вещественный массив, +заданный случайными числами на промежутке [0; 50). Выведите на экран исходный +и отсортированный массивы. + +Пример: +Введите число элементов: 5 +Исходный - [46.11436617832828, 41.62921998361278, 18.45859540989644, 12.128870723745806, 8.025098788570562] +Отсортированный - [8.025098788570562, 12.128870723745806, 18.45859540989644, 41.62921998361278, 46.11436617832828] +""" +import timeit +import random + + +def merge_sort(lst_obj): + if len(lst_obj) > 1: + center = len(lst_obj) // 2 + left = lst_obj[:center] + right = lst_obj[center:] + + merge_sort(left) + merge_sort(right) + + i, j, k = 0, 0, 0 + while i < len(left) and j < len(right): + if left[i] < right[j]: + lst_obj[k] = left[i] + i += 1 + else: + lst_obj[k] = right[j] + j += 1 + k += 1 + + while i < len(left): + lst_obj[k] = left[i] + i += 1 + k += 1 + + while j < len(right): + lst_obj[k] = right[j] + j += 1 + k += 1 + return lst_obj + +orig_list = [random.random() * 50 for _ in range(100)] +print(f'Source array {orig_list}') +print(f'Sorted array {merge_sort(orig_list[:])}') +# замеры +print(timeit.timeit("merge_sort(orig_list)", \ + setup="from __main__ import merge_sort, orig_list", number=1)) + diff --git a/task_3.py b/task_3.py new file mode 100644 index 00000000..b15dab16 --- /dev/null +++ b/task_3.py @@ -0,0 +1,58 @@ +""" +3. Массив размером 2m + 1, где m – натуральное число, заполнен случайным образом. +Найдите в массиве медиану. Медианой называется элемент ряда, делящий его на +две равные части: в одной находятся элементы, которые не меньше медианы, +в другой – не больше медианы. + +Задачу можно решить без сортировки исходного +массива. + +Но если это слишком сложно, то используйте метод сортировки, +который не рассматривался на уроках: Шелла, Гномья, ... + +arr[m] +""" +import random as rnd +from statistics import median +from timeit import timeit + +src = [rnd.randint(1, 100) for _ in range(1, 6000)] + +def find_med_v1(arr): + return median(src) + +def find_med_v2(arr): + return sorted(arr)[len(arr) // 2] + +def find_med_v3(arr): + cnt_ge, cnt_le = 0, 0 + i, j = 0, 0 + ln = len(arr) + while i < ln: + for j in range(0, ln): + if i == j: + continue + if arr[i] >= arr[j]: + cnt_ge +=1 + if arr[i] <= arr[j]: + cnt_le +=1 + if cnt_ge >= ln // 2 and cnt_le >= ln // 2: + return arr[i] + else: + i += 1 + cnt_ge, cnt_le = 0, 0 + continue + +print(find_med_v1(src)) +print(find_med_v2(src)) +print(find_med_v3(src)) + +print(timeit("find_med_v1(src)", setup="from __main__ import find_med_v1, src", number=1)) +print(timeit("find_med_v2(src)", setup="from __main__ import find_med_v2, src", number=1)) +print(timeit("find_med_v3(src)", setup="from __main__ import find_med_v3, src", number=1)) + +""" +Fastest way using "median" from "statistics" 0.0006178999999999768 +Litlle bit worse using "sorted" 0.0006308000000000147 +My realization is nightmare :) 0.058788599999999996 +"""