Project Euler Problem #93

Problem #93 concerns the values that can be obtained by evaluating arithmetic expressions with specific sets of digits. The question reads:

Project Euler Problem 93: Arithmetic expressions
By using each of the digits from the set, {1, 2, 3, 4}, exactly once, and making use of the four arithmetic operations (+, −, *, /) and brackets/parentheses, it is possible to form different positive integer targets.
For example,
8 = (4 * (1 + 3)) / 2
14 = 4 * (3 + 1 / 2)
19 = 4 * (2 + 3) − 1
36 = 3 * 4 * (2 + 1)
Note that concatenations of the digits, like 12 + 34, are not allowed.
Using the set, {1, 2, 3, 4}, it is possible to obtain thirty-one different target numbers of which 36 is the maximum, and each of the numbers 1 to 28 can be obtained before encountering the first non-expressible number.
Find the set of four distinct digits, a < b < c < d, for which the longest set of consecutive positive integers, 1 to n, can be obtained, giving your answer as a string: abcd.

My solution for this problem is very bad as it is essentially just pure brute force. Here is my solution:

Solution #1: Brute Force Approach

We simply look at every subset of 4 of the digits and count the number of consecutive values that can be found by listing the value of every integer arithmetic expression that can be written. Here is an implementation of this approach in Python 2.7:

 '''
 Author: Walker Kroubalkian
 Brute Force Approach to Project Euler Problem #93
 '''
 
 import time
 
 def subset(myList,n):
     l = len(myList)
     if(l==0):
         if(n==0):
             return [[]]
         return []
     if(l<n):
         return []
     if(l==n):
         return [sorted(myList)]
     a = myList[0]
     total = subset(myList[1:],n)
     possible = subset(myList[1:],n-1)
     for x in possible:
         t = x[:]
         t.append(a)
         total.append(sorted(t))
     return total
 
 def permutations(myList):
     l = len(myList)
     if(l==0):
         return []
     if(l==1):
         return [myList]
     a = myList[0]
     b = permutations(myList[1:])
     total = []
     for c in b:
         for x in range(l):
             t = c[0:x]
             t.append(a)
             t.extend(c[x:])
             total.append(t)
     return total
 
 def allTuples(myList,n):
     if(n==0):
         return [[]]
     b = allTuples(myList,n-1)
     total = []
     for x in b:
         for y in myList:
             z = x[:]
             z.append(y)
             total.append(z)
     return total

 def insertOperations(myList):
     operationTriples = allTuples(["+","-","*","/"],3)
     parentheseOptions = [" o o o ","( o o )o ","( o )o o ", "( o )o( o )","(( o )o )o "]
     final = []
     wrongCount = 0
     for p in parentheseOptions:
         for o in operationTriples:
             s = ""
             c = 0
             d = 0
             for x in p:
                 if x==" ":
                     s+=str(float(myList[c]))
                     c+=1
                 elif(x=="o"):
                     s+=str(o[d])
                     d+=1
                 else:
                     s+=x
             try:
                 myValue = eval(s)
                 if(myValue-int(myValue)==0):
                     if int(myValue) not in final:
                         final.append(int(myValue))
                 else:
                     wrongCount+=1
             except:
                 wrongCount+=1
     return final
 
 def projectEulerProblemNinetyThree():
     quadruples = subset([0,1,2,3,4,5,6,7,8,9],4)
     maxFound = 28
     maxQuadruple = [1,2,3,4]
     for x in quadruples:
         y = permutations(x)
         total = []
         for z in y:
             w = insertOperations(z)
             for a in w:
                 if a>0 and a not in total:
                     total.append(a)
         c = 1
         while c in total:
             c+=1
         if(c>maxFound):
             maxFound = c
             maxQuadruple = x
     s = ""
     for a in maxQuadruple:
         s+=str(a)
     return s
 
 start = time.time()
 print projectEulerProblemNinetyThree()
 print ("--- %s seconds ---" % (time.time()-start))
 
 '''
 Prints
 
 1258
 --- 15.6847269535 seconds ---
 
 for given problem.
 ''' 

And with that, we’re done. That took over 15 seconds to run, so I may return to this problem eventually to look for a more efficient solution.

Thanks for reading! See you tomorrow.

Published by Walker Kroubalkian

My name is Walker Kroubalkian. I really enjoy math, computer science, and hiking.

Leave a comment

Design a site like this with WordPress.com
Get started