Last active
April 2, 2025 20:45
-
-
Save sveinn-steinarsson/c64f05363fc017b5eeff239590930e2a to your computer and use it in GitHub Desktop.
Solver for the puzzle game 4=10
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
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