The code:
from itertools import count, permutations
OPERATORS = '+-*( )='
VARIABLES = 'abcdefghijklmnopqrstuvwxyz'
NUMERALS = '1234567890'
VALID_CHARACTERS = OPERATORS + VARIABLES + NUMERALS
def is_expression_valid(expression):
return all(c in VALID_CHARACTERS for c in expression)
def is_expression_consistent(expression, variables):
for index, value in zip(count(1), variables):
expression = expression.replace(value, str(index))
try:
eval(expression.replace("=", "=="))
except SyntaxError:
return False
return True
def extract_variables(expression):
variables = {char for char in expression if char in VARIABLES}
if len(variables) > 10:
raise ValueError()
return variables
def get_expression():
while True:
expression = input(">>> ")
if not is_expression_valid(expression):
print(f"Invalid characters in the expression. Use only from: {VALID_CHARACTERS}")
continue
try:
variables = extract_variables(expression)
except ValueError:
print("Expected at most 10 variable/letters!")
continue
if not is_expression_consistent(expression, variables):
print("Invalid syntax!")
continue
break
return expression, variables
def substitute_expression_format(expression):
return "".join(f"{{{c}}}" if c in VARIABLES else c for c in expression)
def valid_results(expression, variables):
formatted_expression = substitute_expression_format(expression)
for permute in permutations(range(10), len(variables)):
variation = formatted_expression.format(**dict(zip(variables, permute)))
try:
if eval(variation.replace("=", "==")):
yield variation
except SyntaxError:
continue
def main():
while True:
expression, variables = get_expression()
for result in valid_results(expression, variables):
print(result)
if __name__ == "__main__":
main()
Experimenting with different word combos, I had a great day :)