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
21 changes: 21 additions & 0 deletions task_01.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import random

Choose a reason for hiding this comment

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

Похоже вы прослушали то, что было в конце урока.
В функцию не превратили, "ускоритель" не добавили. И сортирует по возрастанию, а не по убыванию.
Да, разворот внизу есть. Но с таким же успехом можно все задачи решить через sorted.


N = 10

a = [0] * N
for i in range(N):
a[i] = random.randrange(-100, 100)
print(f'raw_list = {a}')

for i in range(N - 1):
# print('#' * 66)
# print(i)
for j in range(N - 1 - i):
# print('*' * 66)
# print(j)
if a[j] > a[j + 1]:
a[j], a[j + 1] = a[j + 1], a[j]

print(f'sorted a = {a}')
a_reverse = sorted(a, reverse=True)
print(f'sorted and reversed = {a_reverse}')
28 changes: 28 additions & 0 deletions task_02.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import random

Choose a reason for hiding this comment

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

Это сортировка слиянием? )))
Куда потерялось условие задачи?


N = 10


def sum_(m):
s = 0
while m > 0:
s += m % 10
m = m // 10
return s


a = [0] * N
for i in range(N):
a[i] = random.randrange(0, 50)
print(a)

for i in range(N - 1):
for j in range(N - 1 - i): # i in first loop is 0
if sum_(a[j]) > sum_(a[j + 1]):
a[j], a[j + 1] = a[j + 1], a[j]

print(a)
a_result = []
for i in range(N):
a_result.append(sum_(a[i]))
print(f'{a_result}')

Choose a reason for hiding this comment

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

Прочитал до конца код. Абсолютно уверен, что это не сортировка. Результаты вывода на экран подтверждают моё мнение. Что же это? )))

102 changes: 102 additions & 0 deletions task_03.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import random

M = 10
N = 2 * M + 1

l = [0] * N

Choose a reason for hiding this comment

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

l - без комментариев.

for i in range(N):
l[i] = random.randrange(0, 100)
print(f'raw_list = {l}')
x = sorted(l[:])
print(f'sorted_list = {x}')

# With love to https://habr.com/post/346930/

Choose a reason for hiding this comment

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

)))


def nlogn_median(l):

Choose a reason for hiding this comment

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

Простое решение со встроенной сортировкой.
Хорошо, но расцениваю это как читерство высшего уровня.

n = len(l)
if n % 2 == 1:
return sorted(l)[n // 2]
else:
return sum(sorted(l)[n // 2 - 1: n // 2 + 1]) / 2.0


def quickselect_median(l, pivot_fn=random.choice):
if len(l) % 2 == 1:
return quickselect(l, len(l) / 2, pivot_fn)
else:
return 0.5 * (quickselect(l, len(l) / 2 - 1, pivot_fn) +
quickselect(l, len(l) / 2, pivot_fn))


def quickselect(l, k, pivot_fn):

Choose a reason for hiding this comment

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

Примерно это будет на разборе ДЗ

"""
Выбираем k-тый элемент в списке l (с нулевой базой)
:param l: список числовых данных
:param k: индекс
:param pivot_fn: функция выбора pivot, по умолчанию выбирает случайно
:return: k-тый элемент l
"""
if len(l) == 1:
assert k == 0

Choose a reason for hiding this comment

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

В половине запусков выпадаю тут с ошибкой

return l[0]

pivot = pivot_fn(l)

lows = [el for el in l if el < pivot]
highs = [el for el in l if el > pivot]
pivots = [el for el in l if el == pivot]

if k < len(lows):
return quickselect(lows, k, pivot_fn)
elif k < len(lows) + len(pivots):
# Нам повезло и мы угадали медиану
return pivots[0]
else:
return quickselect(highs, k - len(lows) - len(pivots), pivot_fn)


def pick_pivot(l):
"""
Выбираем хорошй pivot в списке чисел l
Этот алгоритм выполняется за время O(n).
"""
assert len(l) > 0

# Если элементов < 5, просто возвращаем медиану
if len(l) < 5:
# В этом случае мы возвращаемся к первой написанной нами функции медианы.
# Поскольку мы выполняем её только для списка из пяти или менее элементов, она не
# зависит от длины входных данных и может считаться постоянным
# временем.
return nlogn_median(l)

# Сначала разделим l на группы по 5 элементов. O(n)
chunks = chunked(l, 5)

# Для простоты мы можем отбросить все группы, которые не являются полными. O(n)
full_chunks = [chunk for chunk in chunks if len(chunk) == 5]

# Затем мы сортируем каждый фрагмент. Каждая группа имеет фиксированную длину, поэтому каждая сортировка
# занимает постоянное время. Поскольку у нас есть n/5 фрагментов, эта операция
# тоже O(n)
sorted_groups = [sorted(chunk) for chunk in full_chunks]

# Медиана каждого фрагмента имеет индекс 2
medians = [chunk[2] for chunk in sorted_groups]

# Возможно, я немного повторюсь, но я собираюсь доказать, что нахождение
# медианы списка можно произвести за доказуемое O(n).
# Мы находим медиану списка длиной n/5, поэтому эта операция также O(n)
# Мы передаём нашу текущую функцию pick_pivot в качестве создателя pivot алгоритму
# quickselect. O(n)
median_of_medians = quickselect_median(medians, pick_pivot)
return median_of_medians


def chunked(l, chunk_size):
"""Разделяем список `l` на фрагменты размером `chunk_size`."""
return [l[i:i + chunk_size] for i in range(0, len(l), chunk_size)]

print(f'n*logn median = {nlogn_median(l)}')
print(f'quickselect_median = {quickselect_median(l, pivot_fn=random.choice)}')
print(f'determine O(n) = {pick_pivot(l)}') # что-то здесь пошло не так с медианой???

Choose a reason for hiding this comment

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

Привязка к 5.