project-euler/093_arithmetic_expressions.py

99 lines
2.1 KiB
Python

#!/usr/bin/env python3
#Naive and buggy
#check 2 + 8 + 6 + 12 + 48 = 76 per quad
from fractions import Fraction
from itertools import permutations, combinations, starmap
def new_count(c, x):
while x[c] == c+1:
c+=1
return c-1
def test():
c = 27
best = (1,2,3,4)
best_r = []
for i in combinations(range(1, 10), 4):
r = sorted(list(main(i)))
if r[c] == c+1:
best_r = r
best = i
c = new_count(c, r)
return best, c
def naive(s):
r = []
for perm in permutations(s, 4):
r += alt_prod(perm)
return r
def alt_prod(s):
a = add(s[0], mlt(s[1], add(s[2], set([s[3]]) )))
b = mlt(s[0], add(s[1], mlt(s[2], set([s[3]]) )))
return [a, b]
def main(s):
r = []
prods = tree(s, mlt)
sums = tree(s, add)
r += fold(s[::-1], sums[1], mlt)
r += fold(s[::-1], prods[1], add)
r += fold(sums[0][:3], sums[0][3:], mlt_sets)
r += fold(prods[0][:3], prods[0][3:], add_sets)
r += fold(sums[0], prods[0][::-1], add_sets)
r += fold(sums[0], prods[0][::-1], mlt_sets)
r += [add(s[-1], sums[1][0]), mlt(s[-1], prods[1][0])]
r += naive(s)
return set([int(x) for x in set.union(*r) if x == int(x)])
def fold(a, b, f):
return starmap(f, zip(a, b))
def tree(s, f):
sc = []
tr = []
for i in range(4):
for j in range(i+1, 4):
sc.append(f(s[i], set([s[j]]) ))
for k in range(j+1, 4):
tr.append(f(s[k], sc[-1]))
return sc, tr
def add_sets(a, b):
r = set()
for i in a:
r.update(add(i, b))
return r
def mlt_sets(a, b):
r = set()
for i in a:
for j in b:
r.add(i*j)
return r
def add(e, x):
r = set()
for i in x:
r.add(e+i)
if e != i:
r.add(abs(e-i))
return r
def mlt(e, x):
r = set()
for i in x:
r.add(e*i)
r.add(Fraction(1, e) * i)
r.add(Fraction(1, i) * e)
return r
a = set([2, 3, 45, 8])
b = set([4, 6,7])
r = test()
s = ''.join(map(str, r[0]))
print(s)