diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/.idea/algorithms-python-17-04-21.iml b/.idea/algorithms-python-17-04-21.iml
new file mode 100644
index 0000000..a293563
--- /dev/null
+++ b/.idea/algorithms-python-17-04-21.iml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 0000000..105ce2d
--- /dev/null
+++ b/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..81dd32a
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..c95a575
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/task_1.py b/task_1.py
new file mode 100644
index 0000000..06f575f
--- /dev/null
+++ b/task_1.py
@@ -0,0 +1,81 @@
+"""
+Задание 1.
+
+Для каждой из трех задач выполнить следующее:
+
+1) для каждой инструкции рядом в комментарии определите сложность этой инструкции
+2) определите сложность алгоритма в целом
+
+укажите сложность непосредственно в этом файле
+точки, где нужно поработать вам, отмечены знаком '!!!'
+Не забудтье оценить итоговую сложность каждого из трех алгоритмов.
+
+Примечание:
+Если у вас возникают сложности, постарайтесь подумать как можно решить задачу,
+а не писать "мы это не проходили)".
+Алгоритмизатор должен развивать мышление, а это прежде всего практика.
+А без столкновения со сложностями его не развить.
+"""
+
+import random
+
+
+#############################################################################################
+def check_1(lst_obj):
+ """Функция должна создать множество из списка.
+
+ Алгоритм 3:
+ Создать множество из списка
+
+ Сложность: n + с => O(n) - линейная.
+ """
+ lst_to_set = set(lst_obj) # O(n) - линейная
+ return lst_to_set # O(1) - константная
+
+
+#############################################################################################
+def check_2(lst_obj):
+ """Функция должная вернуть True, если все элементы списка различаются.
+
+ Алгоритм 1:
+ Проходимся по списку и для каждого элемента проверяем,
+ что такой элемент отстутствует
+ в оставшихся справа элементах
+
+ Сложность: n * n + с => O(n^2) - квадратичная.
+ """
+ for j in range(len(lst_obj)): # O(n) - линейная (если брать выражение само по себе)
+ if lst_obj[j] in lst_obj[j+1:]: # O(n) - линейная (если брать выражение само по себе)
+ return False # O(1) - константная
+ return True # O(1) - константная
+
+
+#############################################################################################
+def check_3(lst_obj):
+ """Функция должная вернуть True, если все элементы списка различаются.
+
+ Алгоритм 2:
+ Вначале выполним для списка сортировку, далее, сравниваем элементы попарно
+ Если присутствуют дубли, они будут находиться рядом.
+
+ Сложность: n + nlogn + n * c + c => O(n log n) -линейно-логарифмическая
+ (хотя если там не сравнение констант, то сложность квадратичная)
+ """
+ lst_copy = list(lst_obj) # O(n) - линейная
+ lst_copy.sort() # O(n log n) - линейно-логарифмическая
+ for i in range(len(lst_obj) - 1): # O(n) - линейная (если брать выражение само по себе)
+ if lst_copy[i] == lst_copy[i+1]: # O(1) - константная (это же сравнение констант? если конечно элемент списка сам не является списком...)
+ return False # O(1) - константная
+ return True # O(1) - константная
+
+#############################################################################################
+
+
+for j in (50, 500, 1000, 5000, 1000):
+ # Из 100000 чисел возьмем 'j' случайно выбранных
+ # Всего 10 тыс. чисел
+ lst = random.sample(range(-100000, 100000), j)
+
+print(check_1(lst))
+print(check_2(lst))
+print(check_3(lst))
diff --git a/task_2.py b/task_2.py
new file mode 100644
index 0000000..f288758
--- /dev/null
+++ b/task_2.py
@@ -0,0 +1,44 @@
+"""
+Задание 2.
+
+Реализуйте два алгоритма.
+
+Первый, в виде функции, должен обеспечивать поиск минимального значения для списка.
+В основе алгоритма должно быть сравнение каждого числа со всеми другими элементами списка.
+Сложность такого алгоритма: O(n^2) - квадратичная.
+
+Второй, в виде функции, должен обеспечивать поиск минимального значения для списка.
+Сложность такого алгоритма: O(n) - линейная.
+
+Не забудьте указать где какая сложность.
+
+Примечание:
+Построить список можно через списковое включение.
+Если у вас возникают сложности, постарайтесь подумать как можно решить задачу,
+а не писать "мы это не проходили)".
+Алгоритмизатор должен развивать мышление, а это прежде всего практика.
+А без столкновения со сложностями его не развить.
+"""
+
+
+def min_n2(lst): # O(n^2) <= n * (n + c) + c
+ for i in lst:
+ for j in lst:
+ if i > j:
+ break
+ elif i < j and j == lst[-1]:
+ return i
+
+
+def min_n(lst): # O(n) <= n + n * c + c
+ result = lst[0]
+ for i in lst:
+ if result > i:
+ result = i
+ return result
+
+
+user_list = [2, 3, 4, 10, 1, 8]
+
+print(min_n2(user_list))
+print(min_n(user_list))
\ No newline at end of file
diff --git a/task_3.py b/task_3.py
new file mode 100644
index 0000000..e362ba3
--- /dev/null
+++ b/task_3.py
@@ -0,0 +1,71 @@
+"""
+Задание 3.
+
+Для этой задачи:
+1) придумайте 2-3 решения (не менее двух)
+2) оцените сложность каждого решения в нотации О-большое
+3) сделайте вывод, какое решение эффективнее и почему
+
+Примечание:
+Без выполнения пунктов 2 и 3 задание считается нерешенным. Пункты 2 и 3 можно выполнить
+через строки документации в самом коде.
+Если у вас возникают сложности, постарайтесь подумать как можно решить задачу,
+а не писать "мы это не проходили)".
+Алгоритмизатор должен развивать мышление, а это прежде всего практика.
+А без столкновения со сложностями его не развить.
+
+Сама задача:
+Имеется хранилище с информацией о компаниях: название и годовая прибыль.
+Для реализации хранилища можно применить любой подход,
+который вы придумаете, например, реализовать словарь.
+Реализуйте поиск трех компаний с наибольшей годовой прибылью.
+Выведите результат.
+"""
+
+# В задании не указано, что делать, если у двух компаний одинаковая годовая прибыль и это влияет на результат.
+# Поэтому в этом случае в результат попадает случайная(ые) компания(ии) из подобных, если все попасть не могут.
+
+def max3_1(dct): # O(n log n) <= nlogn + 3
+ return sorted(dct, key=dct.get)[-3:]
+
+
+def max3_2(dct): # O(n log n) <= c + n + nlogn + 3
+ lst = list(dct.items())
+ lst.sort(key=lambda i: i[1])
+ return lst[-3:]
+
+
+def max3_3(dct): # O(n) - много кода, но только в одном месте линейная сложность, а в остальных константные
+ result = [] # O(1)
+ min_result = [] # O(1)
+
+ def min_res_func(mr):
+ for i in result: # O(1) ибо длина result всегда 3
+ if i[1] < mr[1]: # O(1)
+ mr = i # O(1)
+ return mr # O(1)
+
+ for key, value in dct.items(): # O(n)
+ if len(result) < 3: # O(1)
+ result.append([key, value]) # O(1)
+ if len(result) == 3: # O(1)
+ min_result = result[0] # O(1)
+ min_result = min_res_func(min_result) # O(1) - ибо длина result всегда 3
+ else: # O(1)
+ if value > min_result[1]: # O(1)
+ result.remove(min_result) # O(1) - ибо длина result всегда 3
+ result.append([key, value]) # O(1)
+ min_result = min_res_func(result[0]) # O(1) - ибо длина result всегда 3
+ return result # O(1)
+
+
+'''
+Вывод - третий вариант имеет наименьшую сложность, однако наибольший размер кода.
+Так что я бы сказал, что первые два варианта эффективнее при небольшом количестве компаний, а третий - при большом.
+'''
+
+companies = {'A': 12000, 'B': 1000, 'C': 2600, 'D': 15000, 'E': 10000}
+
+print(max3_1(companies))
+print(max3_2(companies))
+print(max3_3(companies))
\ No newline at end of file
diff --git a/task_4.py b/task_4.py
new file mode 100644
index 0000000..94e26f3
--- /dev/null
+++ b/task_4.py
@@ -0,0 +1,83 @@
+"""
+Задание 4.
+
+Для этой задачи:
+1) придумайте 2-3 решения (не менее двух)
+2) оцените сложность каждого решения в нотации О-большое
+3) сделайте вывод, какое решение эффективнее и почему
+
+Примечание:
+Без выполнения пунктов 2 и 3 задание считается нерешенным. Пункты 2 и 3 можно выполнить
+через строки документации в самом коде.
+Если у вас возникают сложности, постарайтесь подумать как можно решить задачу,
+а не писать "мы это не проходили)".
+Алгоритмизатор должен развивать мышление, а это прежде всего практика.
+А без столкновения со сложностями его не развить.
+
+Сама задача:
+Пользователи веб-ресурса проходят аутентификацию.
+В системе хранятся логин, пароль и отметка об активации учетной записи.
+
+Нужно реализовать проверку, может ли пользователь быть допущен к ресурсу.
+При этом его учетка должна быть активирована.
+А если нет, то польз-лю нужно предложить ее пройти.
+
+Приложение должно давать ответы на эти вопросы и быть реализовано в виде функции.
+Для реализации хранилища можно применить любой подход,
+который вы придумаете, например, реализовать словарь.
+"""
+
+
+def check_1(dct): # O(1) - всё постоянное
+ while True:
+ user = input('Введите логин: ')
+ try:
+ user = dct[user]
+ break
+ except KeyError:
+ pass
+ if user['activation']:
+ for _ in range(5):
+ password = input('Введите пароль: ')
+ if user['password'] == password:
+ print('Вы вошли')
+ break
+ else:
+ answer = input('Хотите активировать учётную запись?: ')
+ if answer.lower() == 'да':
+ user['activation'] = True
+ print('Ваша учётная запись активирована')
+
+
+def check_2(dct): # O(n) - линейный только цикл по перебору ключей словаря, остальное всё постоянное
+
+ def login_check():
+ for _ in range(5):
+ user = input('Введите логин: ')
+ for key in dct:
+ if key == user:
+ return user
+ print("Превышено количество попыток")
+
+ user = login_check()
+ if dct[user]['activation']:
+ for _ in range(5):
+ password = input('Введите пароль: ')
+ if dct[user]['password'] == password:
+ print('Вы вошли')
+ break
+ else:
+ answer = input('Хотите активировать учётную запись?: ')
+ if answer.lower() == 'да':
+ dct[user]['activation'] = True
+ print('Ваша учётная запись активирована')
+
+
+# Задание сложнее предыдущего по вариативности на мой взгляд, поэтому варианты весьма похожи.
+# Засчёт цикла while True первый вариант может выполняться бесконечно, поэтому второй вариант предпочтительней.
+# Хотя по сути лучший решением была бы комбинация, где во втором варианте при вводе логина, используются не два цикла for, а цикл for и try/except
+
+
+users = {'login1': {'password': 'pass1', 'activation': True}, 'login2': {'password': 'pass2', 'activation': False}}
+check_1(users)
+print(users)
\ No newline at end of file
diff --git a/task_5.py b/task_5.py
new file mode 100644
index 0000000..d839cff
--- /dev/null
+++ b/task_5.py
@@ -0,0 +1,94 @@
+"""
+Задание 5.
+Задание на закрепление навыков работы со стеком
+
+Примечание: в этом задании вспомните ваши знания по работе с ООП
+и опирайтесь на пример урока
+
+Реализуйте структуру "стопка тарелок".
+
+Мы можем складывать тарелки в стопку и при превышении некоторого значения
+нужно начать складывать тарелки в новую стопку.
+
+Структура должна предусматривать наличие нескольких стеков.
+Создание нового стека происходит при достижении предыдущим стеком порогового значения.
+Реализуйте по аналогии с примером, рассмотренным на уроке, необходимые методы,
+для реализации это структуры, добавьте новые методы (не рассмотренные в примере с урока)
+для реализации этой задачи.
+
+После реализации структуры, проверьте ее работу на различных сценариях
+
+Подсказка:
+Отдельне стопки можно реализовать через:
+# 1) созд-е экземпляров стека (если стопка - класс)
+# 2) lst = [[], [], [], [],....]
+"""
+
+# Реализована система стэков при которой после переполнения первого стэка создаётся новый.
+# Каждый стэк кроме первого имеет информацию о своём предшественнике,
+# и каждый стэк кроме крайнего имеет информацию о последователе.
+# Таким образом если заканчиваются тарелки в крайнем стэке, они берутся из предшественника,
+# И если в текущем стэке нет места, создаётся новый.
+# Метод get_quantity возвращает количество тарелок во всех стэках цепи
+
+
+class Plate:
+
+ def __init__(self, color='white', shape='circle'):
+ self.color = color
+ self.shape = shape
+
+
+class Stack:
+
+ def __init__(self, size, previous=None):
+ self.size = size
+ self.previous = previous
+ self.next = None
+ self.plates = []
+
+ def push_in(self, plate):
+ if len(self.plates) < self.size:
+ self.plates.append(plate)
+ elif len(self.plates) >= self.size:
+ if self.next is None:
+ self.next = Stack(self.size, self)
+ self.next.push_in(plate)
+
+ def pop_out(self):
+ if self.next is not None:
+ if not self.next.is_empty():
+ self.next.pop_out()
+ return
+ if not self.is_empty():
+ return self.plates.pop()
+ else:
+ if self.previous is not None:
+ self.previous.pop_out()
+ else:
+ print('Тарелки кончились')
+
+ def is_empty(self):
+ return self.plates == []
+
+ def get_quantity_next(self, init_stack_quantity):
+ if self.next is not None:
+ return self.next.get_quantity_next(init_stack_quantity + len(self.next.plates))
+ else:
+ return init_stack_quantity
+
+ def get_quantity(self):
+ if self.previous is not None:
+ self.previous.get_quantity()
+ else:
+ return self.get_quantity_next(len(self.plates))
+
+
+stack = Stack(5)
+for _ in range(6):
+ stack.push_in(Plate())
+ print(stack.get_quantity())
+for _ in range(7):
+ stack.pop_out()
+ print(stack.get_quantity())
+
diff --git a/task_6.py b/task_6.py
new file mode 100644
index 0000000..e405192
--- /dev/null
+++ b/task_6.py
@@ -0,0 +1,87 @@
+"""
+Задание 6.
+Задание на закрепление навыков работы с очередью
+
+Примечание: в этом задании вспомните ваши знания по работе с ООП
+и опирайтесь на пример урока
+
+Реализуйте структуру "доска задач".
+
+Структура должна предусматривать наличие несольких очередей задач, например
+1) базовой, откуда задачи берутся, решаются и отправляются в список решенных
+2) очередь на доработку, когда нерешенные задачи из первой очереди отправляются
+на корректировку решения
+
+После реализации структуры, проверьте ее работу на различных сценариях
+"""
+
+# Первая созданная для доски задач задача создаёт обе нужные очереди и список решённых задач.
+# Удобнее было бы реализовать также интерфейс для работы с доской задач, но в момент когда я об этом подумал,
+# это требовало бы переделать всю структуру классов, так что пришлось ограничиться ручной проверкой.
+
+class Queue:
+
+ def __init__(self):
+ self.tasks = []
+
+ def to_queue(self, task):
+ self.tasks.insert(0, task)
+
+ def from_queue(self):
+ if len(self.tasks) != 0:
+ return self.tasks.pop()
+ else:
+ print("Задач в очереди нет")
+
+ def next_task_description(self):
+ print(self.tasks[-1].description)
+
+ def get_quantity(self):
+ return len(self.tasks)
+
+ def __str__(self):
+ return str(list(map(str, self.tasks)))
+
+
+class Task:
+
+ def __init__(self, description, to_do=None, to_rework=None, done=None):
+ if to_do is None:
+ to_do = Queue()
+ to_rework = Queue()
+ done = []
+ self.to_do = to_do
+ self.to_rework = to_rework
+ self.done = done
+ self.to_do.to_queue(self)
+ self.description = description
+
+ def add_to_rework(self):
+ self.to_rework.to_queue(self)
+
+ def is_done(self):
+ self.done.append(self)
+
+ def __str__(self):
+ return self.description
+
+
+task = Task('задача 1')
+to_do = task.to_do
+to_rework = task.to_rework
+done = task.done
+
+task2 = Task('задача 2', to_do, to_rework, done)
+print(to_do)
+print(to_rework)
+
+to_do.next_task_description()
+to_do.from_queue().is_done()
+to_do.from_queue().add_to_rework()
+print(to_do)
+print(to_rework)
+
+to_rework.from_queue().is_done()
+print(to_do)
+print(to_rework)
+
diff --git a/task_7.py b/task_7.py
new file mode 100644
index 0000000..4be9e57
--- /dev/null
+++ b/task_7.py
@@ -0,0 +1,57 @@
+"""
+Задание 7.
+Задание на закрепление навыков работы с деком
+
+В рассмотренном на уроке листинге есть один недостаток
+Приведенный код способен "обработать" только строку без пробелов, например, 'топот'
+
+Но могут быть и такие палиндромы, как 'молоко делили ледоколом'
+
+Вам нужно доработать программу так, чтобы она могла выполнить проверку на палиндром
+и в таких строках (включающих пробелы)
+"""
+
+
+class DequeClass:
+ def __init__(self):
+ self.elems = []
+
+ def is_empty(self):
+ return self.elems == []
+
+ def add_to_front(self, elem):
+ self.elems.append(elem)
+
+ def add_to_rear(self, elem):
+ self.elems.insert(0, elem)
+
+ def remove_from_front(self):
+ return self.elems.pop()
+
+ def remove_from_rear(self):
+ return self.elems.pop(0)
+
+ def size(self):
+ return len(self.elems)
+
+
+def pal_checker(string):
+ dc_obj = DequeClass()
+
+ string = ''.join(string.split()) # добавленная строчка
+
+ for el in string:
+ dc_obj.add_to_rear(el)
+
+ still_equal = True
+
+ while dc_obj.size() > 1 and still_equal:
+ first = dc_obj.remove_from_front()
+ last = dc_obj.remove_from_rear()
+ if first != last:
+ still_equal = False
+
+ return still_equal
+
+
+print(pal_checker("молоко делили ледоколом"))
\ No newline at end of file