Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
141 changes: 141 additions & 0 deletions task01.py
Original file line number Diff line number Diff line change
@@ -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(<listcomp>)

#Время варианта №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(<listcomp>)

#Время варианта №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(<listcomp>)

#Время варианта №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}

####################################
####################################
# Выводы

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Отличное исследование получилось.
От себя добавлю, что компилятор всегда обгоняет интерпретатор, поэтому в боевых проектах встроенные функции чаще всего предпочтительнее.

# Самый эффективный по времени - алгоритм №2, который максимально использует встроенные
# механизмы - генератор с фильтрацией и функцию нахождения максимального числа. Алгоритм №1 проигрывает
# ему в 2 раза, Алгоритм №3 - проигрывает в 6 раз. Причем Алгоритм №6 c увеличением размера исходного
# массива начинает проигрывать больше
124 changes: 124 additions & 0 deletions task02.py
Original file line number Diff line number Diff line change
@@ -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}

####################################
####################################
# Выводы

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Отлично получилось.

# В алгоритме Эратосфена поиск изначально ведется всех составных (не простых чисел) и потом методом исключения
# этих чисел находим все остальные (т.е. все простые)
# В алгоритме не Эратосфена поиск ведется сразу простых чисел.
# Так же алгоритм Эратосфеена адаптирован под поиск всех простых чисел в определенной
# последовательности чисел и не адаптирован для ситуации, когда изначально неизвестно какая
# это будет последовательность натуральных чисел и эта последовательность растет. Поэтому алгоритм
# пробегает множенство раз по тем натуральным числам, по которых проверка уже проводилась ранее.
# Алгоритм не Эратосфена не имеет такого недостатка, поэтому показывает значительно лучшие результаты.
1 change: 0 additions & 1 deletion test.txt

This file was deleted.