python - Python 中的 Bulls & Cows(策划者)。应该比较容易

标签 python algorithm

我是 python 的新手,我需要编写一个“公牛和奶牛”游戏(又名 Mastermind) 它是这样的:

一开始你有 2 个输入; 1 代表 secret 的长度(可以是 4-6),第二个代表 secret 的长度(可以是 6-10)。 你可以假设 secret 和猜测都具有给定的长度(你不需要确定) 稍后,您还有另外 2 个输入。 1 代表 secret (一串由空格分隔的数字),第二个代表基数(一串由空格分隔的数字)。 如果 secret 的数字等于或超过基数,程序将输出错误并退出。

举例说明:

5 (First input, length should be 5)
8 (The base. It means that no number is allowed to be 8 or beyond. You are only allowed to use 0,1,2,3,4,5,6,7)
1 2 7 2 5 (this is the secret)
7 2 2 1 1 (this is the guess)

输出:

1 BULLS 3 COWS

另一个例子:

6
9
0 0 0 0 0 6
8 22 2 2 1 4

输出:

0 BULLS 0 COWS

好的,所以我开始编写代码,但我不确定我应该使用什么,所以到目前为止我这样做了:

#get the length of the guess - an int number  between 4(included) to 6(included)
secretL = input()
#get the base of the guess - an int number  between 6(included) to 10(included)
secretB = input()
#get the guess
secret = raw_input()
secretsNumbers = map(int, secret.split())
#turn the chain into a singular INT number in order to make sure each of its digits does not equal or exceeds base, using %10
secretsNumbersMerge = int(''.join(map(str,secretsNumbers)))
newSecretsNumbersMerge = secretsNumbersMerge
while newSecretsNumbersMerge!= 0:
    checker = newSecretsNumbersMerge%10
    if checker<secretBase:
        newSecretsNumbersMerge = newSecretsNumbersMerge/10
    else:
        print ("ERROR")
        quit()

guess = raw_input()
guessNumbers = map(int, guess.split())

到目前为止一切都很好。这确实确保 secret 满足基本要求。现在我正处于检查公牛和母牛的主要位置,但我不太确定如何从这一点开始。

我的想法是先检查公牛,然后将它们移除(这样它就不会与奶牛混在一起),然后检查奶牛,但是是的..我一无所知。

我什至不确定在 Python 中使用什么。

提前致谢!

最佳答案

这是您的代码,但请尝试理解其中的每一行:

import re
from collections import Counter

#get the length of the guess - an int number  between 4(included) to 6(included)
secretL = input()
#get the base of the guess - an int number  between 6(included) to 10(included)
secretB = input()
#get the guess
secret = raw_input()

# Check if the secret input uses a digit greater than the base value
# You can use the check on the next line as well. It can be made faster
# too by using search in place of findall.
# if len(re.findall(r"[^0-" + str(secretB) + r" ]+", secret)):
if sum((i!=" " and int(i) > secretB) for i in secret) > 0:
  print("Error")
  quit()

secretNumbers = map(int, secret.split())
guess = raw_input()
guessNumbers = map(int, guess.split())

# Count the bulls by iterating over the two lists simultaneously
bulls = sum(i==j for i, j in zip(secretNumbers, guessNumbers))

# Remove the bulls before counting the cows
secretNumbers, guessNumbers = zip(*((x,y) for x,y in zip(secretNumbers, guessNumbers) if x!=y))

# Cows are defined as the elements present in both the guess and the secret
# but not in the right position.
# If we ignore duplicates, this is the way to go about it.
cows = len(set(secretNumbers) & set(guessNumbers))

## If we count [1,1,2,4] and [5,3,1,1] to have 2 cows, this is how it should be:
#counter = Counter(secretNumbers) & Counter(guessNumbers)
#cows = sum(counter.itervalues())

print(str(bulls) + " BULLS " + str(cows) + " COWS")

如果有什么不清楚的地方,请告诉我,我会添加解释。

另外,我不知道mastermind的规则,是从你的描述中推断出来的。对于第二个例子,我不清楚你是如何得到 0 头奶牛的。

更新 1

if sum(i > secretB for i in secretNumbers) > 0: how does it work exactly?

请在评论、问题或答案中使用反引号 (`) 来引用小段代码。现在,让我们将这段代码分解成易于理解的部分:

  1. 考虑列表理解[ i > secretB for i in secretNumbers]。这将生成一个 bool 值列表。因此,如果您的基数是 6 并且 secretNumbers 是 [1,2,7,2,5],它将返回 [False, False, True, False, False] . (根据您的评论,这不是规则的解释方式,但我很确定您可以根据需要修改此条件。)
  2. sum()是 Python 中一个非常有用的标准内置函数,它返回传递给它的任何可迭代对象的总和。因此,sum([1,2,3,4]) 将返回 10。
  3. 还有待回答对 bool 值列表求和是什么意思。以这种方式将 True 添加到 True 最初可能看起来很奇怪,但我不认为它是 unpythonic;毕竟,bool is a subclass自 2.3 以来所有版本中的 int:

_

>>>issubclass(bool, int)
True

所以,你去吧:sum(i > secretB for i in secretNumbers) 告诉你输入中有多少数字超过基数。

更新 2:

经过 OP 的澄清,更新 1 的解释不再适用于正在讨论的代码,尽管 OP 现在理解使用列表推导来做强大事情的一般技术。

此外,计算 COWS 的条件已经明确,代码现在列出了两种方法 - 一种是忽略重复项;另一种是忽略重复项。其次是计算每个重复的实例。

关于python - Python 中的 Bulls & Cows(策划者)。应该比较容易,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20006944/

相关文章:

python - 如何获得一个数组,该数组是另一个数组的修改,同时保留原始数组?

java - 给定一个自然数 N,找出不大于 N 且单调非递减数字的最大数

javascript - 为什么这个解决方案在 Javascript 中有效,但在 Python 中无效? (动态编程)

python - NumPy:比较两个数组中的元素

algorithm - 在 log(n) 时间内搜索元素

java - 数组分区最小差异

algorithm - 随机排列

arrays - 确定两个数组在排列方面是否相同?

python - 将函数应用于 a 中的所有条目;分隔列( map ?pandas?)

python - 即使您的程序是静态的,也应该使用错误处理吗?