Search code examples
pythonmathpygamepython-itertools

How to list all solutions in 24 game using Python


Recently I created a 24 game solver with python
Read this website if you do not know what the 24 game is: https://www.pagat.com/adders/24.html

Here is the code:

from itertools import permutations, product, chain, zip_longest
from   fractions  import Fraction as F

solutions = []

def ask4():
    num1 = input("Enter First Number: ")
    num2 = input("Enter Second Number: ")
    num3 = input("Enter Third Number: ")
    num4 = input("Enter Fourth Number: ")
    digits = [num1, num2, num3, num4]
    return list(digits)

def solve(digits, solutions):
    digit_length = len(digits)
    expr_length = 2 * digit_length - 1
    digit_perm = sorted(set(permutations(digits)))
    op_comb = list(product('+-*/', repeat=digit_length-1))
    brackets = ([()] + [(x,y)
    for x in range(0, expr_length, 2)
    for y in range(x+4, expr_length+2, 2)
    if (x,y) != (0,expr_length+1)]
                 + [(0, 3+1, 4+2, 7+3)])
    for d in digit_perm:
        for ops in op_comb:
            if '/' in ops:
                d2 = [('F(%s)' % i) for i in d]
            else:
                d2 = d
            ex = list(chain.from_iterable(zip_longest(d2, ops, fillvalue='')))
            for b in brackets:
                exp = ex[::]
                for insert_point, bracket in zip(b, '()'*(len(b)//2)):
                    exp.insert(insert_point, bracket)
                txt = ''.join(exp)
                try:
                    num = eval(txt)
                except ZeroDivisionError:
                    continue
                if num == 24:
                    if '/' in ops:
                        exp = [(term if not term.startswith('F(') else term[2])
                               for term in exp]
                    ans = ' '.join(exp).rstrip()
                    print("Solution found:", ans)
                    solutions.extend(ans)
                    return ans
    print("No solution found for:", ' '.join(digits))

def main():
    digits = ask4()
    solve(digits, solutions)
    print(len(solutions))
    print("Bye")

main()

Right now, my code only shows one solution for the numbers given, even when there are clearly more solutions.
So if someone knows how to do this please help me
Thanks


Solution

  • Your function is returning as soon as it finds a solution. Delete the return statement. After the loop, you can return the list of all solutions if desired. To check if there were none, see if the length of the list is zero (so you know when to say there are no solutions).

    I would also suggest making solutions local to solve, instead of global.