Существует хорошо известный трюк для вопросов, связанных с построением арифметических выражений с помощью скобок: часто проще использовать обратную полировку.
Вот код, который делает это.
# Compute "a op b", returning None if the result
# is no good (eg: 9/0 or too big).
def do_op(a, op, b):
if op == '+':
return a + b
if op == '-':
return a - b
if op == '*':
return a * b
if op == '/':
if b == 0 or a % b != 0:
return None
return a // b
if op == '**':
# Disallow arguments that would result
# in fractions or huge numbers, being careful
# to allow valid results.
if a == 1:
return a
if a == -1:
return -1 if b % 2 else 1
if a == 0 and b == 0:
return None
if b < 0 or b > 20 or a > 10000 or a < -10000:
return None
return a ** b
assert False
# Generates expressions that result in the given target.
# ops is the a record of the operations applied so far,
# stack is the evaluation stack, and num is the first
# digit that we've not pushed yet.
def sums(ops, stack, num, target):
if not num and len(stack) == 1:
if stack[0] == target:
yield ops
return
# If num is 7, say, try pushing 7, 76, 765, 7654, ..., 7654321.
k = num
for i in xrange(num, 0, -1):
for s in sums(ops + [k], stack + [k], i-1, target):
yield s
k = 10 * k + (i - 1)
# If we've less that 2 things on the stack, we can't apply
# any operations.
if len(stack) < 2:
return
# Try each of the possible ops in turn.
for op in ['+', '-', '*', '/', '**']:
result = do_op(stack[-2], op, stack[-1])
if result is None:
continue
for s in sums(ops + [op], stack[:-2] + [result], num, target):
yield s
# Convert a list of operations that represent an expression in RPN
# into infix notation. Every operation is bracketed, even when
# that's redundant.
def to_infix(ops):
stack = []
for p in ops:
if isinstance(p, int):
stack = stack + [p]
else:
stack = stack[:-2] + ['(%s%s%s)' % (stack[-2], p, stack[-1])]
assert len(stack) == 1
return stack[0]
# Starting with an empty stack (and no operations), with 9 as the first
# unused digit, generate all expressions that evaluate to 2016.
for s in sums([], [], 9, 2016):
print to_infix(s)
Это занимает несколько минут, чтобы бежать, но есть много (более 25000) действительных выражений, оценивающих к 2016 году
Мой любимый (((98 * 76) -5432) * 1).
Если я не понимаю, чего вы пытаетесь достичь, невозможно получить все возможные уравнения, равные 2016, потому что существует бесконечно много решений. – NeverForgetY2K
Вы можете добавить, а затем вычесть одно из конца вашей последовательности операций на неопределенный срок. – ApproachingDarknessFish
@jYager: Я думаю, вы недопонимаете. IIUC, используются только цифры 9,8,7,6,5,4,3,2,1 и только в указанном порядке; существует конечное число различных значений, которые могут быть получены из этих цифр и перечисленных операций. – DSM