Python 如何编写一个程序,使用9到1的数字获取所有方法?

Python 如何编写一个程序,使用9到1的数字获取所有方法?,python,algorithm,math,Python,Algorithm,Math,您可以在9 8 7 6 5 4 3 2 1之间添加任何运算符(包括括号和+-*/**)。 例如 98*76-5432*1=2016 9*8*7*(6+5-4-3)*(2-1)=2016 我写了一个这样的节目 from __future__ import division s = ['+','-','*','/','','(',')'] def calc(s): a=s.split() return eval(''.join(a)) a=['','9','','8','','7'

您可以在9 8 7 6 5 4 3 2 1之间添加任何运算符(包括括号和+-*/**)。 例如
98*76-5432*1=2016
9*8*7*(6+5-4-3)*(2-1)=2016

我写了一个这样的节目

from __future__ import division
s = ['+','-','*','/','','(',')']

def calc(s):
    a=s.split()
    return eval(''.join(a))
a=['','9','','8','','7','','6','','5','','4','','3','','2','','1.','']

def test(tmp):
    if tmp == 20:
        try:
            z = eval(''.join(a))
            if z == 2016:
                print ''.join(a)
        except:
            pass
        return
    for i in s:
        #print a
        a[tmp] = i
        test(tmp+2)
for j in s:
    a[0] = j
    test(2)

但这是不对的,因为数字之间可能存在多个运算符。

对于涉及用括号构造算术表达式的问题,有一个众所周知的技巧:通常使用反向波兰符号更容易

下面是执行此操作的代码

# 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)
#计算“a op b”,如果结果为
#不好(例如:9/0或太大)。
def do_op(a、op、b):
如果op=='+':
返回a+b
如果op='-':
返回a-b
如果op=='*':
返回a*b
如果op=='/':
如果b==0或a%b!=0:
一无所获
返回a//b
如果op=='**':
#不允许会导致错误的参数
#以分数或大数字表示,要小心
#以允许有效的结果。
如果a==1:
归还
如果a==-1:
如果b为%2,则返回-1,否则返回1
如果a==0和b==0:
一无所获
如果b<0或b>20或a>10000或a<-10000:
一无所获
返回a**b
断言错误
#生成导致给定目标的表达式。
#ops是迄今为止应用的操作记录,
#stack是求值堆栈,num是第一个
#我们还没推的数字。
定义和(操作、堆栈、数量、目标):
如果不是num和len(堆栈)==1:
如果堆栈[0]==目标:
收益率操作
返回
#如果num是7,比如说,试着按7,76,765,7654,…,7654321。
k=num
对于x范围内的i(num,0,-1):
对于s的总和(ops+[k],堆栈+[k],i-1,目标):
产量
k=10*k+(i-1)
#如果堆栈上的内容少于2个,则无法应用
#任何行动。
如果len(堆栈)<2:
返回
#依次尝试每种可能的行动。
对于['+'、'-'、'*'、'/'、'**']中的op:
结果=do_op(堆栈[-2],op,堆栈[-1])
如果结果为无:
持续
对于总和中的s(ops+[op],堆栈[:-2]+[result],num,target):
产量
#转换表示RPN中表达式的操作列表
#转换成中缀符号。每个操作都用括号括起来,即使在
#那是多余的。
def到_中缀(ops):
堆栈=[]
对于ops中的p:
如果isinstance(p,int):
堆栈=堆栈+[p]
其他:
堆栈=堆栈[:-2]+['(%s%s%s)'(堆栈[-2],p,堆栈[-1])]
断言len(堆栈)==1
返回堆栈[0]
#从空堆栈开始(没有操作),9作为第一个堆栈
#未使用的数字,生成计算到2016的所有表达式。
总金额([]、[]、9、2016年):
打印到中缀(s)
运行需要几分钟,但有很多(超过25000个)有效表达式计算到2016年


我最喜欢的是(((98*76)-5432)*1)。

对于涉及用括号构造算术表达式的问题,有一个众所周知的技巧:通常使用反向波兰符号更容易

下面是执行此操作的代码

# 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)
#计算“a op b”,如果结果为
#不好(例如:9/0或太大)。
def do_op(a、op、b):
如果op=='+':
返回a+b
如果op='-':
返回a-b
如果op=='*':
返回a*b
如果op=='/':
如果b==0或a%b!=0:
一无所获
返回a//b
如果op=='**':
#不允许会导致错误的参数
#以分数或大数字表示,要小心
#以允许有效的结果。
如果a==1:
归还
如果a==-1:
如果b为%2,则返回-1,否则返回1
如果a==0和b==0:
一无所获
如果b<0或b>20或a>10000或a<-10000:
一无所获
返回a**b
断言错误
#生成导致给定目标的表达式。
#ops是迄今为止应用的操作记录,
#stack是求值堆栈,num是第一个
#我们还没推的数字。
定义和(操作、堆栈、数量、目标):
如果不是num和len(堆栈)==1:
如果堆栈[0]==目标:
收益率操作
返回
#如果num是7,比如说,试着按7,76,765,7654,…,7654321。
k=num
对于x范围内的i(num,0,-1):
对于s的总和(ops+[k],堆栈+[k],i-1,目标):
产量
k=10*k+(i-1)
#如果堆栈上的内容少于2个,则无法应用
#任何行动。
如果len(堆栈)<2:
返回
#依次尝试每种可能的行动。
对于['+'、'-'、'*'、'/'、'**']中的op:
结果=do_op(堆栈[-2],op,堆栈[-1])
如果结果为无:
持续
对于总和中的s(ops+[op],堆栈[:-2]+[result],num,target):
产量
#转换表示RPN中表达式的操作列表
#转换成中缀符号。每个操作都用括号括起来,即使在
#那是多余的。
def到_中缀(ops):
堆栈=[]
对于ops中的p:
如果isinstance(p,int):
堆栈=堆栈+[p]
其他:
堆栈=堆栈[:-2]+['(%s%s%s)'(堆栈[-2],p,堆栈[-1])]
断言len(堆栈)==1
返回堆栈[0]
#从空堆栈开始(没有操作),9作为第一个堆栈
#未使用的数字,生成计算到2016的所有表达式。
总金额([]、[]、9、2016年):
打印到中缀(s)
运行需要几分钟,但有很多(超过25000个)有效表达式计算到2016年


我最喜欢的是(((98*76)-5432)*1)。

除非我误解了你想要实现的目标,否则不可能得到所有可能等于2016的方程,因为有无限多个解。你可以无限期地在操作序列的末尾加上一个,然后减去一个。@jYeager