🐍🧩 5 задач с решениями на Python для начинающих разработчиков
Освоили базу и руки чешутся испытать свои знания на практике? Ловите пять задачек на проверку своих знаний: пишем программу для перевода NRZI кода в двоичный, обнаруживаем лишние символы в строке, определяем «почти палиндром», создаем функцию для замены чисел на слова и находим лучшую покерную комбинацию.
1. Лишний символ
Безумный ученый нашел способ отправлять сообщения в будущее. Есть только две проблемы — иногда символы в каждом сообщении перемешиваются, и всегда добавляется ровно один лишний символ. Напишите программу, которая принимает две строки — исходное корректное сообщение и поврежденное доставленное, — и находит лишний символ.
Формат ввода:
Строка А — исходное сообщение.
Строка Б — доставленное сообщение.
#Пример ввода: スーパーハカー スーパーハッカー
Формат вывода:
Лишний символ в доставленном сообщении.
#Пример вывода: ッ
Решение
Способ 1:
a, b = input(), input() for character in a: b = b.replace(character, '', 1) print(b)
Способ 2:
x = input() + input() for i in x: if x.count(i) % 2 != 0: print(i) break
Способ 3:
lst1, lst2 = list(input()), list(input()) for el1 in lst1: if el1 in lst2: lst2.remove(el1) print(*lst2)
2. Функция PythonGeek
Напишите функцию pythongeek(), которая принимает два целочисленных аргумента a и b (при этом a ≤ b), и возвращает строку, составленную из чисел от a до b включительно и слов Python, Geek и PythonGeek по следующим правилам:
- если число делится без остатка на 3, то вместо него в строку добавляется слово Python;
- если число делится без остатка на 7, то вместо него в строку добавляется слово Geek;
- если число делится без остатка и на 3, и на 7, то вместо него в строку добавляется слово PythonGeek;
- в остальных случаях в строку добавляется само число;
- числа и слова в формируемой строке разделяются пробелами.
Пример вызова функции:
print(pythongeek(14, 21))
Возвращаемая строка:
Geek Python 16 17 Python 19 20 PythonGeek
Решение
Задача кажется простой до момента возвращения значения функции — возвращать нужно именно строку с распакованными значениями (не элементы списка).
Способ 1:
def pythongeek(a, b):
sp = [i for i in range(a, b + 1)]
for i, j in enumerate(sp):
if j % 3 == 0 and j % 7 == 0:
sp[i] = 'PythonGeek'
elif j % 3 == 0:
sp[i] = 'Python'
elif j % 7 == 0:
sp[i] = 'Geek'
else:
sp[i] = str(j)
return ' '.join(sp)
Способ 2:
def pythongeek(a, b):
return ' '.join(('Python' * (i % 3 == 0) + 'Geek' * (i % 7 == 0) or str(i)) for i in range(a, b + 1))
Способ 3:
def pythongeek(a,b):
answer = list(map(lambda n: 'PythonGeek' if(n % 3 == 0 and n % 7 == 0) else ('Python' if n % 3 == 0 else ('Geek' if n % 7 == 0 else str(n))), list(range(a, b + 1))))
return " ".join(answer)
3. NRZI кодирование
NRZI (Non Return to Zero Invertive) — один из способов линейного кодирования. Если имеется некое устройство, которое способно находиться лишь в двух различных состояниях, можно построить диаграмму состояний устройства на каждом такте с помощью двоичных 1 и 0. Напишите программу для перевода NRZI кода в двоичный: изменение состояния устройства в этом случае обозначается двоичной единицей 1, а неизменное состояние принимается за 0.
Формат ввода:
Строка NRZI кода, состоящая из символов _, ‾ и |.
#Пример ввода: _|¯|____|¯|__|¯¯¯
Формат вывода:
Двоичный код.
#Пример вывода: 011000110100
Решение
Способ 1:
code = ' ' + input()
for i in range(1, len(code)):
if code[i] != '|':
print(int(code[i - 1] == '|'), end='')
Способ 2:
print(input().replace("|¯", "1").replace("|_", "1").replace("_", "0").replace("¯", "0"))
Способ 3:
code = input().split('|')
res = '0'
for i in code:
res += '0' * (len(i) - 1) + '1'
print((res[1:-1], res[:-1])[bool(code[0])])
4. Почти палиндром
Строка текста, которую можно превратить в палиндром после удаления одной буквы, называется «почти палиндромом». Напишите программу, которая принимает на вход строку, состоящую из букв, цифр и специальных символов, и определяет, можно ли превратить строку в палиндром, удалив одну из букв. В строке гарантированно есть хотя бы две буквы.
Формат ввода:
Строка, состоящая из букв, цифр и символов.
#Пример ввода: *#14&*@(a)!(@14112)!@$)!@*$!*a)$*099
Формат вывода:
True, если строка является почти палиндромом, или False – в противном случае.
#Пример вывода: True
Решение
Алгоритмы, основанные на срезах строк и проверке на палиндромность с помощью функции any (или [::-1]), позволяют решить эту задачу буквально в пару строк. Но выполнение такого кода занимает слишком много времени, и подобные алгоритмы, как правило, не проходят тесты на временные лимиты.
Способ 1:
s = ''.join([i for i in input() if i.isalpha()])
i, j, c = 0, -1, 0
for i in range(len(s)//2):
if s[i] != s[j]:
c += 1
i += 1
j += -1
print('True' if c == 1 or c == 0 or len(s) <= 2 or s[:-1] == s[:-1][::-1] else 'False')
Способ 2:
def isAlmostPalindrome(s):
for i in range(len(s) // 2):
if s[i] != s[-1 - i] and s[i + 1] != s[-i - 1] and s[i] != s[-i - 2]:
return False
return True
s = ''.join(filter(str.isalpha, input()))
print(isAlmostPalindrome(s))
Способ 3:
s = [elem for elem in input() if elem.isalpha()]
mistake = 0
for i in range(len(s)-1):
if mistake > 1:
break
if s[i] != s[-i-1]:
if s[i] == s[-i-2]:
s.pop(-i-1)
else:
s.pop(i)
mistake += 1
print(mistake <= 1)
5. Лучшая комбинация
Напишите программу, которая принимает на вход строку из 5 чисел от 1 до 13, представляющих собой номера карт, и выводит название лучшей комбинации, которую можно из этих карт составить. Валеты, дамы, короли и тузы обозначаются числами 11, 12, 13 и 1 соответственно.
Традиционные названия комбинаций в покере:
- 4 одинаковые карты – Каре;
- 3 одинаковые карты и 2 другие одинаковые карты – Фулл Хаус;
- 5 последовательно идущих карт – Стрит;
- 3 одинаковые карты – Сет;
- 2 одинаковые карты и 2 другие одинаковые карты – Две пары;
- 2 одинаковые карты – Пара;
- ничего из вышеперечисленного – Старшая карта.
Если в руке окажется 5 одинаковых карт – вывести Шулер.
Формат ввода:
Строка из 5 чисел от 1 до 13 через пробел – номера карт в руке.
#Пример ввода: 4 6 5 7 8
Формат вывода:
Название лучшей комбинации карт.
#Пример вывода: Стрит
Решение
Способ 1:
cards = sorted(map(int, input().split()))
n, x = len(set(cards)), cards.count(cards[2])
if n == 1:
print('Шулер')
elif n == 5 and cards[4] - cards[0] == 4:
print('Стрит')
elif x == 4:
print('Каре')
elif n == 2:
print('Фулл Хаус')
elif x == 3:
print('Сет')
elif n == 3:
print('Две пары')
elif n == 4:
print('Пара')
else:
print('Старшая карта')
Способ 2:
cards = list(sorted(map(int, input().split())))
unique_cards = {crd: cards.count(crd) for crd in cards}
if len(unique_cards) == 1:
print('Шулер')
else:
count = sorted(list(unique_cards.values()))
if count == [1, 4]:
print('Каре')
elif count == [2, 3]:
print('Фулл Хаус')
elif cards == list(range(cards[0], cards[0] + 5)):
print('Стрит')
elif count == [1, 1, 3]:
print('Сет')
elif count == [1, 2, 2]:
print('Две пары')
elif count == [1, 1, 1, 2]:
print('Пара')
else:
print('Старшая карта')
Способ 3:
from collections import Counter
COMBO = [
("Шулер", lambda h: len(set(h)) == 1),
("Каре", lambda h: Counter(h).most_common()[0][1] == 4),
("Фулл Хаус", lambda h: len(set(h))==2),
("Стрит", lambda h: len(set(h))==5 and h[-1]-h[0] == 4),
("Сет", lambda h: Counter(h).most_common()[0][1] == 3),
("Две пары", lambda h: len(set(h))==3),
("Пара", lambda h: len(set(h))==4),
("Старшая карта", lambda h: True)
]
hand = sorted(list(map(int, input().split())))
for c in COMBO:
result, rule = c
if rule(hand):
print(result)
break