Давайте вновь поможем Виталию выяснить, какие вариации вытащить из колоды определённые тройки карт возможны. Напишите программу, которая выводит список вариантов согласно требованиям.
Формат ввода
В первой строке записана масть, которая должна присутствовать в тройке. Во второй строке записан достоинство, которого не должно быть в тройке. В третьей строке записан предыдущий вариант полученный Виталием.
Формат вывода
Выведите следующий вариант расклада.
Примечание
Обратите внимание: валет-дама-король-туз лексикографически упорядочены. Но «10 …» лексикографически младше, чем «2 …», а бубны младше, чем пики.
Масти в именительном и родительном падежах:
Именительный | Родительный |
---|---|
буби | бубен |
пики | пик |
трефы | треф |
черви | червей |
Пример
Ввод
пики
10
9 пик, король треф, туз червей
Вывод
9 пик, король червей, туз бубен
Ввод
трефы
король
2 червей, туз пик, туз треф
Вывод
2 червей, туз треф, туз червей
Решение
Развитие предыдущей задачи. Если вы решали ее с помощью combinations(), то задача сводится к поиску нужной комбинации в списке и выводе на печать следующего элемента.
Но довольно часто, в предыдущей задачи используется permutations(), которая генерирует другую последовательность карт, потому что позволяет себе переставлять элементы комбинаций не сохраняя их изначальный порядок. В результате в ответах следующая комбинация не будет совпадать с ожидаемой.
Дополним алгоритм предыдущей задачи:
После того как сгенерировали тройки карт, перебираем их по одной и сравниваем с тем, что имеем на руках. Если тройки совпали, то ставим флажок, чтобы на следубщей итерации напечатать тройку карт и выйти из цикла.
В идеале цикл надо “закольцевать”, на случай если на руках “последняя” тройка карт из списка, но Яндекс не проверяет этот случай в тестах, поэтому предлагаемая реализация этого не предусматривает.
Посмотреть код
Решение
from itertools import chain, combinations, product
suit = input().strip()
rank = input().strip()
hand = input()
suits = {'буби': 'бубен', 'пики': 'пик', 'трефы': 'треф', 'черви': 'червей'}
ranks = ['10', '2', '3', '4', '5', '6', '7', '8', '9', 'валет', 'дама', 'король', 'туз']
ranks.remove(rank)
deck = product(ranks, suits.values())
triplets = combinations(deck, 3)
triplets = [triplet for triplet in triplets if suits[suit] in chain.from_iterable(triplet)]
triplets.sort()
print_next = False
for triplet in triplets:
if print_next:
print(', '.join(f'{rank} {suit}' for rank, suit in triplet))
break
if ', '.join(f'{rank} {suit}' for rank, suit in triplet) == hand:
print_next = True
Вариант с поиском индекса предыдущего варианта.
from itertools import product, combinations, chain
suits = {‘буби’: ‘бубен’, ‘пики’: ‘пик’,
‘трефы’: ‘треф’, ‘черви’: ‘червей’}
cards = [’10’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’,
‘валет’, ‘дама’, ‘король’, ‘туз’]
main_suit = input()
cards.remove(input())
previous_combination = list(chain(input().split(‘, ‘)))
previous_combination = tuple(tuple(i for i in j.split()) for j in previous_combination)
pack = product(cards, suits.values())
triples = combinations(pack, 3)
combination = [triple for triple in triples if suits[main_suit] in chain.from_iterable(triple)]
next_index = combination.index(previous_combination) + 1
print(‘, ‘.join(f'{card} {suit}’ for card, suit in combination[next_index]))
Решил задачу по васянски, даже показывать стыдно, два вопроса есть.
Вопрос первый: мой код изначально очень похож на ваше решение, в том числе 15-ая строка, однако я не преобразовывал итератор chain.from в список. Собсна вопрос, а зачем там преобразование в список? вроде же может прям сам итератор перебирать?
Вопрос второй: очень хотелось бы разобраться, но даже сформулировать толком не могу, как вообще понять f-строку в строчном выражении, условие в начале понятно, зачем брейк понятно, вообще вся логика решения понятна, но эти f-строки с двумя переменными, которые что? ссылаются на rank, suit, но этим именам уже присвоены input(), и как (f-строка) соответствует двум перменными цикла for, если есть какое-то дословно буквальное чайное объяснение логики этих строчек, можно пожалуйста сформулировать, гугл бессилен
Вы совершенно правы, преобразовывать итератор в список нет никакой необходимости. Осталось по невнимательности, что, конечно меня не сильно извиняет. Спаибо, что помогаете вычистить код.
Насчет f-строк там все довольно просто. rank и suit сюда попадают из цикла, который перебирает triplets. В triplet, из которых состоит triplets находятся три кортежа (достоинство, масть) которые попадают соотвественно в rank и suit.