If I understood the process correctly, you want to count what bull
s are not None
, and how many cow
s are not None
:
reduce(lambda (bcount, ccount), (b, c): (bcount + (b is not None), ccount + (c is not None)),
bullsandcows(given, number), (0, 0))
This increments a counter only if the bull
or cow
value is not None
. The test produces a boolean, which is a subclass of int
with False == 0
and True == 1
; summing an integer and a boolean results in another integer.
Since you are feeding it non-empty strings, you could simplify it to:
reduce(lambda (bcount, ccount), (b, c): (bcount + bool(b), ccount + bool(c)),
bullsandcows(given, number), (0, 0))
I'd rewrite bullsandcows()
to:
def bullsandcows(given, number):
given, number = map(str, (given, number))
for g, n in zip(given, number):
if g == n:
yield (g, None)
elif g in number:
yield (None, g)
e.g. use zip()
to pair up the digits of given
and number
.
Demo:
>>> def bullsandcows(given, number):
... given, number = map(str, (given, number))
... for g, n in zip(given, number):
... if g == n:
... yield (g, None)
... elif g in number:
... yield (None, g)
...
>>> given, number = 8241, 1234
>>> list(bullsandcows(given, number))
[('2', None), (None, '4'), (None, '1')]
>>> reduce(lambda (bcount, ccount), (b, c): (bcount + bool(b), ccount + bool(c)),
... bullsandcows(given, number), (0, 0))
(1, 2)
Note that unpacking in function arguments was removed from Python 3 and the reduce()
built-in has been delegated to library function; your code is decidedly Python 2 only.
To make it work in Python 3 you need to import functools.reduce()
and adjust the lambda to not use unpacking:
from functools import reduce
reduce(lambda counts, bc: (counts[0] + bool(bc[0]), counts[1] + bool(bc[1])),
bullsandcows(given, number), (0, 0))