Skip to content

Instantly share code, notes, and snippets.

@yammesicka
Last active September 9, 2017 11:46
Show Gist options
  • Save yammesicka/9100317d62089247ed77738f12e7f0a3 to your computer and use it in GitHub Desktop.
Save yammesicka/9100317d62089247ed77738f12e7f0a3 to your computer and use it in GitHub Desktop.
A solution for "use the following digits and basic operators to get the result X"
import itertools
from typing import (Sequence, Iterable, Iterator,
Union, Optional,
List, NamedTuple)
ALLOWED_OPERATORS = ('*', '/', '+', '-') # , '**)
REPEAT_NUMBERS = False
DigitsSequence = Union[str, Sequence[Union[str, int]]]
class Answer(NamedTuple):
solution: Optional[int]
expression: str
def normalize_input(digits: DigitsSequence) -> List[str]:
if not all(map(str.isdecimal, digits)):
print("'Digits' must be consisted of decimal numbers.")
return []
return list(map(str, digits))
def any_order(items: Sequence, length: Optional[int]=None,
allow_repeats: bool=True) -> Iterable:
if length is None:
length = len(items)
if allow_repeats:
yield from itertools.product(items, repeat=length)
else:
yield from itertools.permutations(items, r=length)
def zip_to_str(expression: Iterable) -> str:
return ''.join(''.join(i) for i in expression)
def get_answer(digits: List[str], operators: Sequence) -> Answer:
zipped_expression = itertools.zip_longest(digits, operators, fillvalue='')
expression = zip_to_str(zipped_expression)
try:
return Answer(solution=eval(expression), expression=expression)
except ZeroDivisionError:
return Answer(solution=None, expression=expression)
def solver(allowed_digits: DigitsSequence, solution: int) -> Iterator[str]:
assert isinstance(solution, int), "Solution must be a number."
digits = normalize_input(allowed_digits)
for operators in any_order(ALLOWED_OPERATORS, length=len(digits)-1):
for digits_option in any_order(digits, allow_repeats=REPEAT_NUMBERS):
answer = get_answer(digits_option, operators)
if answer.solution == solution:
yield answer.expression
if __name__ == '__main__':
for solution in solver('1679', solution=10):
print(solution)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment