diff --git a/task01.py b/task01.py new file mode 100644 index 0000000..e16b85a --- /dev/null +++ b/task01.py @@ -0,0 +1,141 @@ +# Задание №1 +# Проанализировать скорость и сложность одного любого алгоритма из разработанных в рамках домашнего задания первых трех уроков. +# Примечание. Идеальным решением будет: +# ● выбрать хорошую задачу, которую имеет смысл оценивать, +# ● написать 3 варианта кода (один у вас уже есть), +# ● проанализировать 3 варианта и выбрать оптимальный, +# ● результаты анализа вставить в виде комментариев в файл с кодом (не забудьте указать, для каких N вы проводили замеры), +# ● написать общий вывод: какой из трёх вариантов лучше и почему. + + +# Задание +# В массиве найти максимальный отрицательный элемент. Вывести на экран его значение и позицию в массиве. +# Примечание к задаче: пожалуйста не путайте «минимальный» и «максимальный отрицательный». Это два +# абсолютно разных значения. + +# Вариант №1 +# Последовательно перебираем все элементы, ищем в них отрицательные и запоминаем наиболее максимальное +def get_max_min_1(array): + max_ = None + for inx, val in enumerate(array[:-1]): + if val < 0: + if max_ is None or val > max_: + max_ = val + return max_ + + +# Вариант №2 +# Находим все отрицательные числа и находим максимальное среди них, используя встроенную функцию + +def get_max_min_2(array): + neg_array = [x for x in array if x < 0] + return max(neg_array) + + +# Вариант №3 +# Сортируем исходный массив по возврастанию и ищем методом половинного деления переход с отрицательного +# на положительное + +def get_max_min_3(array): + a = sorted(array) + pos = len(a) // 2 + while ((a[pos] >= 0 )and a[pos-1] <= 0 or a[pos] <= 0 and a[pos-1] >= 0) == False: + if a[pos] > 0: + a = a[:pos] + else: + a = a[pos:] + pos = len(a) // 2 + if a[pos] < 0: + return a[pos] + else: + return a[pos-1] + + + +##################### +# Результаты +import random + +n = int(input("Введите размер массива случайных чисел:")) + +#array = [45, 44, -47, 9, 47, -9, 44, -2, 41, 9, 11, 55, 155, 33, 0, -14] +array = [random.randint(-n,n) for _ in range(n)] +print(array) +print("Максимальное отрицательное число вар1:", get_max_min_1(array)) +print("Максимальное отрицательное число вар2:", get_max_min_2(array)) +print("Максимальное отрицательное число вар3:", get_max_min_3(array)) + +##################### +# Оцениваем алгоритмы +import timeit +import cProfile + +# timeit +s = """ +get_max_min_1(array) +""" +print("Время варианта №1:", timeit.timeit(s,number=100,globals=globals())) + +s = """ +get_max_min_2(array) +""" +print("Время варианта №2:", timeit.timeit(s,number=100,globals=globals())) + +s = """ +get_max_min_3(array) +""" +print("Время варианта №3:", timeit.timeit(s,number=100,globals=globals())) + +# cProfile +print("Оценка Вариант №1 через cProfile") +cProfile.run("get_max_min_1(array)") + +print("Оценка Вариант №2 через cProfile") +cProfile.run("get_max_min_2(array)") + +print("Оценка Вариант №3 через cProfile") +cProfile.run("get_max_min_3(array)") + +# 10000 элементов +#Время варианта №1: 0.18727370500000085 +# 1 0.002 0.002 0.002 0.002 task01.py:18(get_max_min_1) + +#Время варианта №2: 0.08653298099999951 +# 1 0.000 0.000 0.001 0.001 task01.py:30(get_max_min_2) +# 1 0.001 0.001 0.001 0.001 task01.py:31() + +#Время варианта №3: 0.21902450499999926 +# 1 0.000 0.000 0.002 0.002 task01.py:39(get_max_min_3) +# 12 0.000 0.000 0.000 0.000 {built-in method builtins.len} + +# 50000 элементов +#Время варианта №1: 0.8808438039999995 +# 1 0.009 0.009 0.009 0.009 task01.py:18(get_max_min_1) + +#Время варианта №2: 0.42420562800000017 +# 1 0.000 0.000 0.004 0.004 task01.py:30(get_max_min_2) +# 1 0.003 0.003 0.003 0.003 task01.py:31() + +#Время варианта №3: 2.334317992 +# 1 0.001 0.001 0.024 0.024 task01.py:39(get_max_min_3) +# 15 0.000 0.000 0.000 0.000 {built-in method builtins.len} + +# 100000 элементов +#Время варианта №1: 2.0827101420000007 +# 1 0.021 0.021 0.021 0.021 task01.py:18(get_max_min_1) + +#Время варианта №2: 0.9937122910000005 +# 1 0.000 0.000 0.010 0.010 task01.py:30(get_max_min_2) +# 1 0.008 0.008 0.008 0.008 task01.py:31() + +#Время варианта №3: 6.081710614 +# 1 0.002 0.002 0.060 0.060 task01.py:39(get_max_min_3) +# 15 0.000 0.000 0.000 0.000 {built-in method builtins.len} + +#################################### +#################################### +# Выводы +# Самый эффективный по времени - алгоритм №2, который максимально использует встроенные +# механизмы - генератор с фильтрацией и функцию нахождения максимального числа. Алгоритм №1 проигрывает +# ему в 2 раза, Алгоритм №3 - проигрывает в 6 раз. Причем Алгоритм №6 c увеличением размера исходного +# массива начинает проигрывать больше diff --git a/task02.py b/task02.py new file mode 100644 index 0000000..a6cd954 --- /dev/null +++ b/task02.py @@ -0,0 +1,124 @@ +# Задание №2 +# Написать два алгоритма нахождения i-го по счёту простого числа. +# Функция нахождения простого числа должна принимать на вход натуральное и +# возвращать соответствующее простое число. Проанализировать скорость и +# сложность алгоритмов. + +# Вариант №1 +# Классический алгоритм Решето Эратосфена + +def get_simple_number_erato(n): + #Функция прокалывает дырки + def prokalyvaem_dyrki(arr, n): # передаем масив и простое число + start_search = n**2 + for digit in arr[start_search::n]: + if digit != 0: # если он не равен нулю, то + arr[digit] = 0 + return arr + + lst = [] + arr = [] + arr.append(0); arr.append(0) # заполняем первый и второй нулями + while len(lst) != n: + arr.append(len(arr)) +# for inx,a in enumerate(arr[2:], 2): +# if arr[inx] != 0: # если он не равен нулю, то мы нашли простое число и: +# prokalyvaem_dyrki(arr, a) + for a in arr[2:]: + if a != 0: # если он не равен нулю, то мы нашли простое число и: + prokalyvaem_dyrki(arr, a) + lst = [x for x in arr if x != 0] + + return lst[-1] + + +# Вариант №2 +# Поиск простых чисел не используя алгоритм Решето Эротасфена + +def get_simple_number(n): + lst = [2] + i = 3 + while len(lst) != n: + for j in lst: + if j**2-1 > i: + lst.append(i) + break + if (i % j == 0): + break + else: + lst.append(i) + i +=2 + return lst[-1] + +##################### +# Результаты + +n = int(input("Введите порядковый номер простого числа:")) + +num = get_simple_number_erato(n) +print("Алгоритм Эр. Простое число:", num) + +num = get_simple_number(n) +print("Алгоритм не Эр. Простое число:", num) + +##################### +# Оцениваем алгоритмы +import timeit +import cProfile + +# timeit +s = """ +num = get_simple_number_erato(n) +""" +print("Время Эр.:", timeit.timeit(s,number=50,globals=globals())) + + +s = """ +num = get_simple_number(n) +""" +print("Время не Эр.:", timeit.timeit(s,number=50,globals=globals())) + + +# cProfile +print("Оценка Эратосвена через cProfile") +cProfile.run("get_simple_number_erato(n)") + +print("Оценка не Эратосвена через cProfile") +cProfile.run("num = get_simple_number(n)") + +# 20ое простое число +# Эр.: 0.06512603000000006 +# 851 0.001 0.000 0.001 0.000 task02.py:12(prokalyvaem_dyrki) + +# Не Эр.: 0.0037111219999999 +# 36 0.000 0.000 0.000 0.000 {built-in method builtins.len} +# 19 0.000 0.000 0.000 0.000 {method 'append' of 'list' objects} + + +# 70ое простое число +# Эр.: 1.23841424 +# 13891 0.024 0.000 0.024 0.000 task02.py:12(prokalyvaem_dyrki) + +#Не Эр.: 0.024541724999999737 +# 175 0.000 0.000 0.000 0.000 {built-in method builtins.len} +# 69 0.000 0.000 0.000 0.000 {method 'append' of 'list' objects} + + +# 120ое простое число +# Эр.: 3.9926523650000005 +# 43511 0.074 0.000 0.074 0.000 task02.py:12(prokalyvaem_dyrki) +#Не Эр.: 0.05030167399999996 +# 330 0.000 0.000 0.000 0.000 {built-in method builtins.len} +# 119 0.000 0.000 0.000 0.000 {method 'append' of 'list' objects} + +#################################### +#################################### +# Выводы +# В алгоритме Эратосфена поиск изначально ведется всех составных (не простых чисел) и потом методом исключения +# этих чисел находим все остальные (т.е. все простые) +# В алгоритме не Эратосфена поиск ведется сразу простых чисел. +# Так же алгоритм Эратосфеена адаптирован под поиск всех простых чисел в определенной +# последовательности чисел и не адаптирован для ситуации, когда изначально неизвестно какая +# это будет последовательность натуральных чисел и эта последовательность растет. Поэтому алгоритм +# пробегает множенство раз по тем натуральным числам, по которых проверка уже проводилась ранее. +# Алгоритм не Эратосфена не имеет такого недостатка, поэтому показывает значительно лучшие результаты. \ No newline at end of file diff --git a/test.txt b/test.txt deleted file mode 100644 index 56a6051..0000000 --- a/test.txt +++ /dev/null @@ -1 +0,0 @@ -1 \ No newline at end of file