Напишите улучшенный код для идентификации действительной серии из восьми карт., например 4H,5S,AC,7C,8H,AH,0S,JC
. Обратите внимание, что комбинация карт может включать в себя символы Wild (как мы видим в нашем примере, где Туз треф заменяет шестерку, а туз червей заменяет девятку), но она должна включать как минимум две «естественные» карты (т. Е. не-подстановочные знаки). Также обратите внимание, что последовательность карточек важна для этого типа группы, и что 4H,5S,AC,8C,7H,AH,AS,AC
, например, не является правильной прямой восьмеркой, так как это не последовательность. Тузы являются единственными дикими картами и должны представлять другую карту. Разрешены дубликаты карт.
Входы карты находятся в списке из 2 строк значений со значением:
- От 2 до 9 — от 2 до 9
- 0 — за 10
- J — для Джека
- Q — для королевы
- K — для короля
- A — для Ace
Масти показаны со значениями S (пика), C (булава), H (сердце), D (ромб).
- Пример ввода для проверки:
4H,5S,AC,7C,8H,AH,0S,JC
Выход: True
- Пример ввода для проверки:
AH,5S,AC,7C,AH,AH,AS,AC
Выход: True
- Пример ввода для проверки:
4H,5S,AC,8C,7H,AH,AS,AC
Выход: ложь
Вот мой код:
group = input().split(",")
if len(group) == 8:
#check for ace
ace = [0 for card in group if card[0] == 'A']
run_vals = {"0": 10, "J": 11, "Q": 12, "K":13}
if len(ace) < 6:
miss_count = 0
for index in range(len(group)-1):
if group[index][0] == "A":
miss_count += 1
if group[index+1][0] == "A" and index == len(group)-2:
miss_count += 1
continue
else:
continue
if group[index+1][0] == "A" and index == len(group)-2:
miss_count += 1
continue
if group[index+1][0] == "A" and index <len(group)-2:
continue
if group[index+1][0] in run_vals:
num1 = run_vals[group[index+1][0]]
else:
num1 = int(group[index+1][0])
if group[index][0] in run_vals:
num2 = run_vals[group[index][0]]
else:
num2 = int(group[index][0])
if (num1 - num2) != 1:
miss_count += 1
if miss_count == len(ace):
print(True)
else:
print(False)
elif len(ace) == 6:
ace_in_between = 0
range_limits = [card for card in group if card[0] != "A"]
for index in range(len(group)):
if index > group.index(range_limits[0]) and index< group.index(range_limits[1]):
ace_in_between += 1
range_limits = [run_vals[val[0]] if val[0] in run_vals else val[0] for val in range_limits]
if ace_in_between + 1 == (int(range_limits[1]) - int(range_limits[0]) ):
print(True)
else:
print(False)
else:
print(False)
else:
print(False)
3 ответа
Хорошие новости! В вашем коде есть много возможностей для улучшения! (Как это для положительного спина?)
Подсчет тузов
ace = [0 for card in group if card[0] == 'A']
Этот код создает список (ace
), который содержит только 0
элементов, равных количеству тузов в group
. Содержание списка никогда не используется, только длина. Наконец, дважды запрашивается длина списка.
Это очень сложная реализация для простого подсчета количества тузов:
aces = sum(card[0] == 'A' for card in group)
Или чуть менее наискось:
aces = sum(1 for card in group if card[0] == 'A')
Карты декодирования
run_vals = {"0": 10, "J": 11, "Q": 12, "K":13}
...
if group[index+1][0] in run_vals:
num1 = run_vals[group[index+1][0]]
else:
num1 = int(group[index+1][0])
if group[index][0] in run_vals:
num2 = run_vals[group[index][0]]
else:
num2 = int(group[index][0])
...
range_limits = [run_vals[val[0]] if val[0] in run_vals else val[0] for val in range_limits]
if ace_in_between + 1 == (int(range_limits[1]) - int(range_limits[0]) ):
Я вижу много in run_vals
тесты и int(...)
слепки. Представьте, насколько чище мог бы выглядеть ваш код, если бы вы просто заполнили все поля run_vals
?
run_vals = {"A": 1,
"2": 2, "3": 3, "4": 4, "5": 5,
"6": 6, "7": 7, "8": 8, "9": 9,
"0": 10, "J": 11, "Q": 12, "K":13}
Я добавил сопоставление «А» к 1
просто для полноты. Это позволит вам протестировать all(card[0] in run_vals for card in group)
чтобы проверить, что все карты имеют действительный ранг, например, никто не подбирает «1 пик».
В этом отношении вы также можете проверить действительные костюмы, такие как all(card[1] in {'C', 'D', 'H', 'S'} for card in group)
, чтобы не попасться в «7 пентаклей».
Прямо
Проблема была бы предельно простой, если бы не было джокеров. Вы могли написать:
rank = [run_vals[card[0]] for card in group]
start = rank[0]
for idx in range(len(rank)):
if rank[idx] != start + idx:
return False
return True
Было бы легко поддерживать дикие карты, если бы мы знали, что первая карта не туз. Мы могли бы просто добавить исключение для тузов:
for idx in range(len(rank)):
if rank[idx] != start + idx and rank[idx] != 1:
return False
Начальное значение
Что будет, если первой картой будет туз? Что ж, вторая карта (предположим, что это не туз) диктует, что начало было на один ранг ниже. Или, если это был туз, то третья карта и так далее:
for idx in range(len(rank)):
if rank[idx] == 1:
start = rank[idx] - idx
break
else:
return False # Only aces exist!
Функции!
Ваш код — это один сложный сценарий без каких-либо функций. Если вы еще не научились их писать, учитесь. Если вы узнали, используйте их!
Переработанный код
Следующий код является повторной реализацией некоторых из вышеперечисленных идей. Однако петли вроде for idx in len(range(list))
были заменены на более Pythonic for idx, value in enumerate(list)
петли. Циклы, возвращающие False
если одна итерация дает False
результат был заменен на all(...)
оператор с выражением генератора. Он также демонстрирует некоторые подсказки типов, """docstrings"""
(включая использование (doctest
), чтобы помочь написать код, более понятный для других и содержащий встроенные модульные тесты.
Еще одно улучшение — это формулировка задачи, которая гласит, что должно быть как минимум 2 «естественных» карты. Вместо того, чтобы проверять количество тузов, которое меньше или равно 6 — число, которое нигде не фигурирует в формулировке задачи, — выполняется прямая проверка с заданным значением 2.
RANK = dict(zip("A234567890JQK", range(1, 14)))
WILD = RANK['A']
def straight_of_eight(card_string: str) -> bool:
"""
Determine if a string of cards is an ascending straight,
with at least 2 natural cards.
>>> straight_of_eight("4H,5S,AC,7C,8H,AH,0S,JC")
True
>>> straight_of_eight("4H,5S,AC,8H,7C,AH,0S,JC")
False
"""
ranks = [RANK[card[0]] for card in card_string.split(',')]
if len(ranks) != 8:
return False # Were not given exactly 8 cards
if sum(rank != WILD for rank in ranks) < 2:
return False # Not enough natural cards
# Determine starting rank for the straight
start = next(rank - idx for idx, rank in enumerate(ranks) if rank != WILD)
return 2 <= start <= 6 and all(rank == idx or rank == WILD
for idx, rank in enumerate(ranks, start))
if __name__ == '__main__':
import doctest
doctest.testmod()
group = input()
print(straight_of_eight(group))
это из проекта 2 COMP10001? Простым решением является использование алгоритма Снида (ранее называвшегося Чака) для решения этой проблемы и поиска других типов групп.
Я предлагаю вам не использовать какой-либо код, предоставленный другими пользователями stackoverflow, в качестве ответа для проекта. Это серьезный академический проступок, и университет узнает об этом с помощью своего алгоритма обнаружения, а также другие студенты обнаружат это и, возможно, сообщат об этом. Риск получения 0 баллов и потенциального исключения НЕ стоит того, чтобы заработать эти дополнительные баллы.
Большое спасибо!
— Алоизиус Ребейро