Работа цикла for в игре "Быки и коровы". Питон
Делаю игру "Быки и коровы". Если буква из testword есть в correctword и стоит в том же месте, то bulls += 1 Если буква из testword есть в correctword, но не на своем месте, то cows += 1 Программа работает правильно во всех случаях, кроме одного: когда игрок предлагает слово, в котором есть повторяющиеся буквы. Пример:
correctword = [м, о, н, а, х] # загаданное компьютером слово
testword = [м, о, н, н, н] # тестовое слово, которое ввел игрок. программа сравнивает его с загаданным
bulls = 0
cows = 0
for i in correctword: # для каждой буквы в correctword
if i in testword: # если одна из букв есть в testword
if testword.index(i) == correctword.index(i): # и если индексы букв совпадают, то:
bulls += 1 # увеличить счетчик bulls на 1
else:
cows += 1 # иначе увеличить счетчик cows на 1
В описанном случае программа считает: bulls = 3, cows = 0, а должна: bulls = 3, cows = 2
Если поменять итерируемый список:
for i in testword:
if i in correctword:
то также именно эта ситуация считается неверно, но уже иначе: bulls =5, cows =0.
Думаю, дело в том, что list.index(i) возвращает положение ПЕРВОГО элемента со значением i, а надо не первого, а каждого. Что делать?
Ответы (3 шт):
python3
def each(s: str, f):
sL = len(s)
i = 0
while i < sL:
val = s[i]
f(val, i)
i += 1
def foo(a: str, b: str):
# aL = len(a)
bL = len(b)
bulls = 0
cows = 0
def q(v, i: int):
nonlocal bulls, cows
if i >= bL:
return
isOK = v == b[i]
if isOK:
bulls += 1
else:
cows += 1
# print(b[i])
each(a, q)
return [bulls, cows]
bulls, cows = foo('монах', 'моннн')
print(bulls)
print(cows)
o ,-
- VSCode + python3 https://stackoverflow.com/a/47196099/4794368
Вот вариант решения, использующий словари и множества позиций для каждого символа.
correctword = ['м', 'о', 'н', 'а', 'х'] # загаданное компьютером слово
testword = ['м', 'о', 'н', 'н', 'н'] # тестовое слово, которое ввел игрок. программа сравнивает его с загаданным
bulls = 0
cows = 0
correctword_map = {} # словарь {символ: множество позиций с этим символом} для корректного слова
testword_map = {} # словарь {символ: множество позиций с этим символом} для проверяемого слова
length = len(correctword) # длина слова
for c in set(correctword): # для каждого уникального символа
correctword_map[c] = set() # инициализируем значение в словаре пустым множеством
testword_map[c] = set()
for i in range(length): # пробегаем по каждой позиции в обоих словах и
if correctword[i] == c:
correctword_map[c].add(i) # добавляем в множество позиции, в которых встречается этот символ
if testword[i] == c:
testword_map[c].add(i)
for c in set(correctword): # для каждого уникального символа
correctword_positions = correctword_map[c] # берем множество позиций этого символа в корректном слове
testword_positions = testword_map[c] # берем множество позиций этого символа в проверяемом слове
bulls += len(testword_positions.intersection(correctword_positions)) # быки - прибавляем размер пересечения этих множеств
cows += len(testword_positions.difference(correctword_positions)) # коровы - прибавляем размер разности этих множеств
print(bulls)
print(cows)
В принципе, можно сделать проще.
Например, не пробегать дважды по set(correctword), а делать всё за один проход. Да и словари набивать не обязательно, можно просто работать с множествами.
В общем, есть простор для творческой доработки.
Объяснение в комментариях к циклу.
correctword = 'монах' # загаданное компьютером слово
testword = 'моннн' # тестовое слово, которое ввел игрок
bulls = 0
cows = 0
for c1, c2 in zip(correctword, testword):
if c1 == c2: # символы совпали - бык
bulls += 1
elif c2 in correctword: # символы не совпали,
# но второй символ есть в первом слове - корова
cows += 1
print(bulls, cows)