Обновить results/top_tracks.txt
This commit is contained in:
parent
9964f1fc0f
commit
5b86d3c13b
@ -8,3 +8,388 @@ Rap God | Eminem | hip-hop | 950000 прослушиваний
|
|||||||
Wake Me Up | Avicii | electronic | 920000 прослушиваний
|
Wake Me Up | Avicii | electronic | 920000 прослушиваний
|
||||||
Without Me | Eminem | hip-hop | 880000 прослушиваний
|
Without Me | Eminem | hip-hop | 880000 прослушиваний
|
||||||
Levels | Avicii | electronic | 870000 прослушиваний
|
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]
|
||||||
|
```
|
||||||
|
|
||||||
|
Логика:
|
||||||
|
- сравниваем текущие элементы двух списков;
|
||||||
|
- если равны — добавляем в ответ и двигаем оба указателя;
|
||||||
|
- если один меньше — двигаем только его;
|
||||||
|
- так не нужен двойной цикл, и алгоритм работает быстро.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user