use Counter
to count guess
and secret
and sum their overlap. Then use zip
to count A
.
s, g = Counter(secret), Counter(guess)
a = sum(i == j for i, j in zip(secret, guess))
return '%sA%sB' % (a, sum((s & g).values()) - a)
Share my solution using similar idea BUT in an old fashion coding style...
def getHint(self, secret, guess):
"""
:type secret: str
:type guess: str
:rtype: str
"""
secret_map, guess_map = {}, {}
bull_count, cow_count = 0, 0
for i in range(len(secret)):
if secret[i] == guess[i]:
bull_count += 1
else:
if secret[i] in secret_map:
secret_map[secret[i]] += 1
else:
secret_map[secret[i]] = 1
if guess[i] in guess_map:
guess_map[guess[i]] += 1
else:
guess_map[guess[i]] = 1
for i in guess_map:
if i in secret_map:
cow_count += min(secret_map[i], guess_map[i])
return '%sA%sB' % (bull_count, cow_count)
also old style but cleaner
class Solution(object):
def getHint(self, secret, guess):
bull, cow = 0, 0
s = {} # secret hashtable
g = {} # guess hashtable
for i in xrange(len(secret)):
if secret[i] == guess[i]:
bull += 1
else:
s[secret[i]] = s.get(secret[i], 0) + 1
g[guess[i]] = g.get(guess[i], 0) + 1
for k in s:
if k in g:
cow += min(s[k], g[k])
return '{0}A{1}B'.format(bull, cow)
Cool solution! Here is my version using defaultdict (beats ~87%):
def getHint(self, secret, guess):
bulls = 0
sh = defaultdict(int)
gh = defaultdict(int)
for s, g in zip(secret, guess):
if s == g:
bulls += 1
else:
sh[s] += 1
gh[g] += 1
cows = sum(min(sh[k], gh[k]) for k in sh)
return "{}A{}B".format(bulls, cows)