Skip to content

Instantly share code, notes, and snippets.

@sveinn-steinarsson
Last active June 10, 2023 20:45
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sveinn-steinarsson/c64f05363fc017b5eeff239590930e2a to your computer and use it in GitHub Desktop.
Save sveinn-steinarsson/c64f05363fc017b5eeff239590930e2a to your computer and use it in GitHub Desktop.
Solver for the puzzle game 4=10
"""
This simple 4=10 game solver is intended for educational purposes only.
"""
import sys
from itertools import product, permutations
WELCOME = """Solver for the puzzle game 4=10
Get the game app: https://fourequalsten.app/
Insert a four digit number.
Usage: python solver.py [number]
Examples:
python solver.py 1466"""
#
# Hardcoded settings which could be fun to change :)
#
EQUALS_NUMBER = 10 # What is your target number
OPERATORS = ["+", "-", "*", "/"] # What operators can be used
def eval_expression(exp):
"""Takes in an expression and returns the result"""
try:
# Warning! The eval() function is considered unsecure because it can allow the execution of arbitrary code.
# Evaluate expressions using a more secure method if you want to use this code with untrusted input.
return eval(exp, {}, {})
except ZeroDivisionError:
return None # Divided by zero is undefined.
def solve(input_number):
"""Takes in a number and prints out all possible solutions according to 4=10 game rules"""
# Create a set of unique permutations from the input number
unique_numbers = set(["".join(n) for n in permutations(input_number)])
# Create a list of all operators combinations
operators_combinations = [o for o in product(OPERATORS, repeat=3)]
# Define an empty set to store the solutions
solutions = set()
for unique_number in unique_numbers:
a, b, c, d = [digit for digit in unique_number] # Split the number into single digits
for operators in operators_combinations:
o1, o2, o3 = [operator for operator in operators]
#
# Create an expression without parentheses
#
expression = "".join((a, o1, b, o2, c, o3, d))
result_without_parentheses = eval_expression(expression)
if result_without_parentheses == EQUALS_NUMBER:
solutions.add(expression) # Add solution to set
#
# Apply parentheses but only add solution if parentheses are not redundant
#
expression = "".join(("(", a, o1, b, ")", o2, c, o3, d)) # (a b) c d
result_with_parentheses = eval_expression(expression)
if (result_without_parentheses != result_with_parentheses and result_with_parentheses == EQUALS_NUMBER):
solutions.add(expression)
expression = "".join(("(", a, o1, b, o2, c, ")", o3, d)) # (a b c) d
result_with_parentheses = eval_expression(expression)
if (result_without_parentheses != result_with_parentheses and result_with_parentheses == EQUALS_NUMBER):
solutions.add(expression)
expression = "".join((a, o1, "(", b, o2, c, o3, d, ")")) # a (b c d)
result_with_parentheses = eval_expression(expression)
if (result_without_parentheses != result_with_parentheses and result_with_parentheses == EQUALS_NUMBER):
solutions.add(expression)
expression = "".join((a, o1, b, o2, "(", c, o3, d, ")")) # a b (c d)
result_with_parentheses = eval_expression(expression)
if (result_without_parentheses != result_with_parentheses and result_with_parentheses == EQUALS_NUMBER):
solutions.add(expression)
expression = "".join((a, o1, "(", b, o2, c, ")", o3, d)) # a (b c) d
result_with_parentheses = eval_expression(expression)
if (result_without_parentheses != result_with_parentheses and result_with_parentheses == EQUALS_NUMBER):
solutions.add(expression)
if len(solutions) == 0:
print("The number", input_number, "has no solutions.")
return
# Print out the solutions
for solution in solutions:
print(f"{solution} = {EQUALS_NUMBER}")
#
# Calculate and print out basic summary information
#
total_count = len(solutions)
with_parentheses_count = len(list(filter(lambda s: "(" in s, solutions)))
print("--------------")
print(f"The number {input_number} has {total_count} solutions.")
print(f"Without parentheses {total_count - with_parentheses_count}")
print(f"With parentheses {with_parentheses_count}")
print("--------------")
if __name__ == "__main__":
if len(sys.argv) != 2:
print(WELCOME) # No number
else:
number = sys.argv[1] # Read the number from parameter
# Check if number is valid
if len(number) != 4:
print("Error! Number not four digits.")
elif not number.isdigit():
print("Error! Input is not a number.")
else:
solve(number)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment