396 lines
14 KiB
Plaintext
396 lines
14 KiB
Plaintext
Blinding Lights | The Weeknd | pop | 1500000 прослушиваний
|
||
Lose Yourself | Eminem | hip-hop | 1200000 прослушиваний
|
||
Starboy | The Weeknd | pop | 1100000 прослушиваний
|
||
Save Your Tears | The Weeknd | pop | 1050000 прослушиваний
|
||
Die For You | The Weeknd | pop | 990000 прослушиваний
|
||
Smells Like Teen Spirit | Nirvana | rock | 980000 прослушиваний
|
||
Rap God | Eminem | hip-hop | 950000 прослушиваний
|
||
Wake Me Up | Avicii | electronic | 920000 прослушиваний
|
||
Without Me | Eminem | hip-hop | 880000 прослушиваний
|
||
Levels | Avicii | electronic | 870000 прослушиваний
|
||
|
||
git clone https://git.vyatsu.ru/stud203985/MusicAnalyzer.git
|
||
cd ИМЯ_РЕПО
|
||
git config user.name "ТВОЕ ИМЯ"
|
||
git config user.email "ТВОЯ_ПОЧТА"
|
||
notepad solution.py
|
||
git add solution.py
|
||
git commit -m "Add skeleton"
|
||
git add solution.py
|
||
git commit -m "Implement solution"
|
||
git push
|
||
без глобал находясь в папке только в репе моем сейвинтсся
|
||
|
||
|
||
================
|
||
def some_function(x):
|
||
return x
|
||
|
||
|
||
def main():
|
||
print(some_function(...))
|
||
print(some_function(...))
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main()
|
||
=============================
|
||
|
||
# 1. is_armstrong(n: int) -> bool
|
||
# Проверяет, является ли число числом Армстронга.
|
||
# Идея: переводим число в строку, считаем количество цифр,
|
||
# затем суммируем каждую цифру в степени количества цифр.
|
||
def is_armstrong(n: int) -> bool:
|
||
digits = str(n)
|
||
power = len(digits)
|
||
total = 0
|
||
|
||
for ch in digits:
|
||
total += int(ch) ** power
|
||
|
||
return total == n
|
||
|
||
|
||
# 2. intersection_of_sorted(a: list, b: list) -> list
|
||
# Находит пересечение двух отсортированных списков без дубликатов.
|
||
# Идея: используем два указателя i и j.
|
||
# Если элементы равны - добавляем в результат.
|
||
# Если элемент в первом списке меньше - двигаем i.
|
||
# Иначе двигаем j.
|
||
def intersection_of_sorted(a: list, b: list) -> list:
|
||
i = 0
|
||
j = 0
|
||
result = []
|
||
|
||
while i < len(a) and j < len(b):
|
||
if a[i] == b[j]:
|
||
if not result or result[-1] != a[i]:
|
||
result.append(a[i])
|
||
i += 1
|
||
j += 1
|
||
elif a[i] < b[j]:
|
||
i += 1
|
||
else:
|
||
j += 1
|
||
|
||
return result
|
||
|
||
|
||
# 3. longest_increasing_subsequence(arr: list) -> list
|
||
# Находит самую длинную возрастающую подпоследовательность.
|
||
# Идея: динамическое программирование.
|
||
# dp[i] хранит длину наибольшей возрастающей подпоследовательности,
|
||
# которая заканчивается в элементе arr[i].
|
||
# prev[i] хранит индекс предыдущего элемента в этой подпоследовательности.
|
||
def longest_increasing_subsequence(arr: list) -> list:
|
||
if not arr:
|
||
return []
|
||
|
||
n = len(arr)
|
||
dp = [1] * n
|
||
prev = [-1] * n
|
||
|
||
for i in range(n):
|
||
for j in range(i):
|
||
if arr[j] < arr[i] and dp[j] + 1 > dp[i]:
|
||
dp[i] = dp[j] + 1
|
||
prev[i] = j
|
||
|
||
max_index = 0
|
||
for i in range(1, n):
|
||
if dp[i] > dp[max_index]:
|
||
max_index = i
|
||
|
||
result = []
|
||
while max_index != -1:
|
||
result.append(arr[max_index])
|
||
max_index = prev[max_index]
|
||
|
||
result.reverse()
|
||
return result
|
||
|
||
|
||
# 4. remove_duplicate_chars(s: str) -> str
|
||
# Удаляет из строки все повторяющиеся символы,
|
||
# оставляя только первое вхождение каждого символа.
|
||
# Идея: используем множество seen для хранения уже встреченных символов.
|
||
def remove_duplicate_chars(s: str) -> str:
|
||
seen = set()
|
||
result = ""
|
||
|
||
for ch in s:
|
||
if ch not in seen:
|
||
seen.add(ch)
|
||
result += ch
|
||
|
||
return result
|
||
|
||
|
||
# 5. most_frequent_value(d: dict) -> tuple
|
||
# Находит значение, которое чаще всего встречается среди значений словаря.
|
||
# Возвращает кортеж: (значение, частота).
|
||
# Идея: сначала считаем частоты значений в словаре counts,
|
||
# потом ищем значение с максимальной частотой.
|
||
def most_frequent_value(d: dict) -> tuple:
|
||
counts = {}
|
||
|
||
for value in d.values():
|
||
counts[value] = counts.get(value, 0) + 1
|
||
|
||
best_value = None
|
||
best_count = 0
|
||
|
||
for value, count in counts.items():
|
||
if count > best_count:
|
||
best_value = value
|
||
best_count = count
|
||
|
||
return best_value, best_count
|
||
|
||
|
||
# 6. gcd(a: int, b: int) -> int
|
||
# Находит наибольший общий делитель двух чисел.
|
||
# Идея: алгоритм Евклида.
|
||
# Пока b не равно 0, заменяем:
|
||
# a = b
|
||
# b = a % b
|
||
def gcd(a: int, b: int) -> int:
|
||
while b != 0:
|
||
a, b = b, a % b
|
||
return a
|
||
|
||
|
||
# 7. frequency_analysis(text: str, n: int) -> list
|
||
# Находит n самых частых слов в тексте.
|
||
# Игнорирует регистр и некоторые знаки препинания.
|
||
# Возвращает список кортежей: (слово, частота).
|
||
# Идея:
|
||
# 1. Переводим текст в нижний регистр
|
||
# 2. Удаляем знаки препинания
|
||
# 3. Разбиваем на слова
|
||
# 4. Считаем частоты слов
|
||
# 5. Сортируем по частоте по убыванию
|
||
def frequency_analysis(text: str, n: int) -> list:
|
||
text = text.lower()
|
||
|
||
for ch in ",.!?:;()-":
|
||
text = text.replace(ch, " ")
|
||
|
||
words = text.split()
|
||
counts = {}
|
||
|
||
for word in words:
|
||
counts[word] = counts.get(word, 0) + 1
|
||
|
||
result = sorted(counts.items(), key=lambda x: x[1], reverse=True)
|
||
return result[:n]
|
||
|
||
|
||
# 8. lcm(a: int, b: int) -> int
|
||
# Находит наименьшее общее кратное двух чисел.
|
||
# Идея: используем формулу:
|
||
# lcm(a, b) = a * b // gcd(a, b)
|
||
def lcm(a: int, b: int) -> int:
|
||
return a * b // gcd(a, b)
|
||
|
||
==============================================================
|
||
|
||
1) Цикл по строке `for ch in s:`
|
||
Зачем: пройти по строке посимвольно.
|
||
Когда: удалить повторы, посчитать буквы, собрать новую строку.
|
||
Что на вход: строка `s`. Что на выход: строка, число или `bool`.
|
||
Переменные: `s` — вся строка, `ch` — текущий символ.
|
||
|
||
Пример:
|
||
```python
|
||
def remove_a(s: str) -> str:
|
||
result = ""
|
||
|
||
for ch in s:
|
||
if ch != "a":
|
||
result += ch
|
||
|
||
return result
|
||
|
||
print(remove_a("abacada")) # bcd
|
||
```
|
||
|
||
Логика:
|
||
- идем по каждому символу;
|
||
- если символ не `"a"`, добавляем в `result`;
|
||
- в конце возвращаем новую строку.
|
||
|
||
2) Цикл по списку `for x in arr:`
|
||
Зачем: пройти по всем элементам списка.
|
||
Когда: найти максимум, сумму, отфильтровать элементы.
|
||
Что на вход: список `arr`. Что на выход: число, список, `bool`.
|
||
Переменные: `arr` — список, `x` — текущий элемент.
|
||
|
||
Пример:
|
||
```python
|
||
def only_positive(arr: list) -> list:
|
||
result = []
|
||
|
||
for x in arr:
|
||
if x > 0:
|
||
result.append(x)
|
||
|
||
return result
|
||
|
||
print(only_positive([-2, 5, 0, 7, -1])) # [5, 7]
|
||
```
|
||
|
||
Логика:
|
||
- идем по элементам;
|
||
- если элемент подходит, добавляем в новый список.
|
||
|
||
3) Множество `set()`
|
||
Зачем: хранить только уникальные элементы и быстро проверять, встречался ли элемент раньше.
|
||
Когда: удалить дубликаты в строке или списке.
|
||
Что на вход: строка или список. Что на выход: строка/список без повторов.
|
||
Переменные: `seen` — множество уже встреченных элементов.
|
||
|
||
Пример:
|
||
```python
|
||
def remove_duplicate_chars(s: str) -> str:
|
||
seen = set()
|
||
result = ""
|
||
|
||
for ch in s:
|
||
if ch not in seen:
|
||
seen.add(ch)
|
||
result += ch
|
||
|
||
return result
|
||
|
||
print(remove_duplicate_chars("abacabad")) # abcd
|
||
```
|
||
|
||
Логика:
|
||
- если символ еще не встречался, добавляем его в `seen` и в ответ;
|
||
- если уже был, пропускаем.
|
||
|
||
4) Словарь-счетчик `counts[x] = counts.get(x, 0) + 1`
|
||
Зачем: считать, сколько раз встречается каждый элемент.
|
||
Когда: частота слов, чисел, символов.
|
||
Что на вход: список, строка, слова текста. Что на выход: словарь частот или самый частый элемент.
|
||
Переменные: `counts` — словарь, `x` — текущий элемент.
|
||
|
||
Пример:
|
||
```python
|
||
def count_numbers(arr: list) -> dict:
|
||
counts = {}
|
||
|
||
for x in arr:
|
||
counts[x] = counts.get(x, 0) + 1
|
||
|
||
return counts
|
||
|
||
print(count_numbers([1, 2, 1, 3, 2, 1])) # {1: 3, 2: 2, 3: 1}
|
||
```
|
||
|
||
Логика:
|
||
- для каждого элемента увеличиваем счетчик;
|
||
- если элемента еще нет, начинаем с 0.
|
||
|
||
5) Цикл `while`
|
||
Зачем: повторять действия, пока выполняется условие.
|
||
Когда: НОД, работа с цифрами числа, два указателя.
|
||
Что на вход: зависит от задачи. Что на выход: зависит от задачи.
|
||
Переменные: обычно счетчик или значения, которые меняются в цикле.
|
||
|
||
Пример:
|
||
```python
|
||
def gcd(a: int, b: int) -> int:
|
||
while b != 0:
|
||
a, b = b, a % b
|
||
return a
|
||
|
||
print(gcd(18, 24)) # 6
|
||
```
|
||
|
||
Логика:
|
||
- пока `b` не ноль, заменяем числа;
|
||
- когда `b` стал 0, ответ хранится в `a`.
|
||
|
||
6) Преобразование числа в строку `str(n)`
|
||
Зачем: удобно работать с цифрами числа.
|
||
Когда: Армстронг, сумма цифр, палиндром числа.
|
||
Что на вход: число `n`. Что на выход: число, `bool` и т.д.
|
||
Переменные: `n` — число, `digits = str(n)` — строка с цифрами, `ch` — одна цифра как символ.
|
||
|
||
Пример:
|
||
```python
|
||
def sum_of_digits(n: int) -> int:
|
||
total = 0
|
||
|
||
for ch in str(n):
|
||
total += int(ch)
|
||
|
||
return total
|
||
|
||
print(sum_of_digits(1234)) # 10
|
||
```
|
||
|
||
Логика:
|
||
- переводим число в строку;
|
||
- идем по символам `"1"`, `"2"`, `"3"`, `"4"`;
|
||
- превращаем каждый символ обратно в число и суммируем.
|
||
|
||
7) Сортировка `sorted(...)`
|
||
Зачем: упорядочить элементы или взять топ-N.
|
||
Когда: отсортировать числа, слова по частоте, результаты.
|
||
Что на вход: список или `dict.items()`. Что на выход: отсортированный список.
|
||
Переменные: `arr` — список, `x` — элемент, `x[1]` — второй элемент кортежа.
|
||
|
||
Пример:
|
||
```python
|
||
def top_words(counts: dict) -> list:
|
||
return sorted(counts.items(), key=lambda x: x[1], reverse=True)
|
||
|
||
print(top_words({"cat": 3, "dog": 2, "bird": 1}))
|
||
# [('cat', 3), ('dog', 2), ('bird', 1)]
|
||
```
|
||
|
||
Логика:
|
||
- `counts.items()` дает пары `(слово, частота)`;
|
||
- `key=lambda x: x[1]` значит сортировать по частоте;
|
||
- `reverse=True` — по убыванию.
|
||
|
||
8) Два указателя
|
||
Зачем: эффективно обрабатывать два отсортированных списка.
|
||
Когда: пересечение, слияние, сравнение отсортированных списков.
|
||
Что на вход: два списка `a` и `b`. Что на выход: обычно новый список.
|
||
Переменные: `i` — индекс в первом списке, `j` — индекс во втором.
|
||
|
||
Пример:
|
||
```python
|
||
def intersection_of_sorted(a: list, b: list) -> list:
|
||
i = 0
|
||
j = 0
|
||
result = []
|
||
|
||
while i < len(a) and j < len(b):
|
||
if a[i] == b[j]:
|
||
result.append(a[i])
|
||
i += 1
|
||
j += 1
|
||
elif a[i] < b[j]:
|
||
i += 1
|
||
else:
|
||
j += 1
|
||
|
||
return result
|
||
|
||
print(intersection_of_sorted([1, 2, 3, 4], [2, 4, 6])) # [2, 4]
|
||
```
|
||
|
||
Логика:
|
||
- сравниваем текущие элементы двух списков;
|
||
- если равны — добавляем в ответ и двигаем оба указателя;
|
||
- если один меньше — двигаем только его;
|
||
- так не нужен двойной цикл, и алгоритм работает быстро.
|
||
|
||
|
||
|