Skip to content

Instantly share code, notes, and snippets.

@yammesicka
Last active January 28, 2017 04:12
Show Gist options
  • Save yammesicka/fa0d590c023f653c389e843b173cad7a to your computer and use it in GitHub Desktop.
Save yammesicka/fa0d590c023f653c389e843b173cad7a to your computer and use it in GitHub Desktop.
Safe opener - trying to take the fun from spamming Facebook with useless riddles :(
GIVEN_CLUES = (
# Number, bulls, cows
('073', 1, 0),
('041', 0, 1),
('360', 0, 2),
('827', 0, 0),
('786', 0, 1)
)
def check_guess_validity(number, guess):
if not (isinstance(number, str) and isinstance(guess, str)):
raise TypeError("Number and guess must be strings.")
if not (number.isdecimal() and guess.isdecimal()):
raise ValueError("Number and guess must include only digits.")
if len(number) != len(guess):
raise ValueError("Number and guess must be in the same length.")
def _count_bulls(number, guess):
return sum(1 for i, j in zip(number, guess) if i == j)
def _count_cows(number, guess):
return sum(1 for i, j in zip(number, guess) if i != j and i in guess)
def get_bulls_and_cows(number, guess):
check_guess_validity(number, guess)
return [_count_bulls(number, guess), _count_cows(number, guess)]
def is_matching(guess, clues):
for clue, *bulls_and_cows in clues:
if not (get_bulls_and_cows(clue, guess) == bulls_and_cows):
return False
return True
def find_result(clues):
num_of_digits = len(clues[0][0])
for i in range(10**num_of_digits):
guess = str(i).zfill(num_of_digits)
if is_matching(guess, clues):
return guess
if __name__ == '__main__':
print(find_result(GIVEN_CLUES))
# Tests section
LONG_NUMBERS = (
('123', 3, 0),
('321', 1, 2),
('000', 0, 0),
('333', 1, 2),
)
tests = {
_count_bulls: (
('123', '123', 3),
('987', '654', 0),
('987', '789', 1),
('987', '789', 1),
('981', '980', 2)
),
_count_cows: (
('012', '012', 0),
('123', '321', 2),
('000', '111', 0),
('123', '345', 1),
('123', '312', 3),
),
is_matching: (
('012', (('012', 3, 0),), True),
('123', LONG_NUMBERS, True),
('321', LONG_NUMBERS, False),
('987', LONG_NUMBERS, False),
('111', LONG_NUMBERS, False),
)
}
for function, tests_for_function in tests.items():
for *arguments, result in tests_for_function:
assert function(*arguments) == result
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment