Python 如何编写一个程序,使用9到1的数字获取所有方法?
您可以在9 8 7 6 5 4 3 2 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'
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