如何对 3 个整数执行所有可能的算术运算组合?
How to perform all possible combinations of arithmetic operations on 3 integers?
假设我有三个整数。我想获得通过在它们之间执行所有 16(*, /, +, -
的 4x4)操作获得的所有可能值的列表。
就像我有 3 4 1
,我们应该得到值 1、2、6、7、8、9、11、12,
13、15和16。即
res = num1 (op1) num2 (op2) num3
其中运算符为:
["**", "*/", "*+", "*-", "/*", "//", "/+", "/-", "+*", "+/", "++", "+-", "-*", "-/", "-+", "--"]
However, the catch is that division can only be possible if x%y==0
i.e. divisor is factor of dividend.
所以,到目前为止,我已经能够暴力破解每一个操作,但缺少一些答案。我还定义了一个自定义除法运算以考虑 捕获量。
我需要 return 一个包含所有正值的唯一值的列表。
我目前的代码很乱,但这是为了它。这也遗漏了一些值。
def div(x, y):
if x!=0 and y!=0:
if x%y==0:return x/y
else:return None
ops_lis = ["**", "*/", "*+", "*-", "/*", "//", "/+", "/-", "+*", "+/", "++", "+-", "-*", "-/", "-+", "--"]
d1, d2, d3 = map(int, input().split())
cal_lis, res_lis = [], []
for op in ops_lis:
if op[0] == "*" and op[1] == "*":cal_lis.append(d1*d2*d3)
if op[0] == "*" and op[1] == "/":
if div(d1*d2, d3) != None:cal_lis.append(div(d1*d2, d3))
cal_lis.append(div(d1*d2, d3))
if op[0] == "*" and op[1] == "+":
cal_lis.append(d1*(d2+d3))
cal_lis.append((d1*d2)+d3)
if op[0] == "*" and op[1] == "-":
cal_lis.append(d1*d2-d3)
cal_lis.append(d1*(d2-d3))
cal_lis.append((d1*d3)-d2)
if op[0] == "/" and op[1] == "*":cal_lis.append(div(d1, d2*d3))
if op[0] == "/" and op[1] == "/":
if div(d1, d2) == None or div(d2, d3) == None:
cal_lis.append(None)
else:
cal_lis.append(div(div(d1, d2), d3))
if op[0] == "/" and op[1] == "+":
if div(d1, d2) == None:
cal_lis.append(None)
else:
cal_lis.append(div(d1, d2)+d3)
if op[0] == "/" and op[1] == "-":
if div(d1, d2) == None:
cal_lis.append(None)
else:
cal_lis.append(div(d1, d2)-d3)
if op[0] == "+" and op[1] == "*":
cal_lis.append(d1+d2*d3)
cal_lis.append((d1+d2)*d3)
cal_lis.append((d1+d3)*d2)
if op[0] == "+" and op[1] == "/":
if div(d2, d3) == None:
cal_lis.append(None)
else:
cal_lis.append(d1+div(d2, d3))
if op[0] == "+" and op[1] == "+":cal_lis.append(d1+d2+d3)
if op[0] == "+" and op[1] == "-":cal_lis.append(d1+d2-d3)
if op[0] == "-" and op[1] == "*":
cal_lis.append(d1-d2*d3)
cal_lis.append((d1-d2)*d3)
cal_lis.append((d1-d3)*d2)
if op[0] == "-" and op[1] == "/":
if div(d2, d3) == None:cal_lis.append(None)
else: cal_lis.append(d1-div(d2, d3))
if div(d1-d2, d3) == None:cal_lis.append(None)
else: cal_lis.append(div(d1-d2, d3))
if op[0] == "-" and op[1] == "+":cal_lis.append(d1-d2+d3)
if op[0] == "-" and op[1] == "-":cal_lis.append(d1-d2-d3)
# print(cal_lis)
cal_lis = [int(cal) for cal in cal_lis if cal!=None]
for res in cal_lis:
if (res > 0 and res not in res_lis):
res_lis.append(int(res))
for a in sorted(res_lis):
print(a, end=" ")
print()
鉴于划分条件也为真,是否有一种有效的方法来执行此任务(也许使用树?)?
如有任何帮助,我们将不胜感激...
编辑:添加约束
计算必须符合以下格式:
number = dice1 op1 dice2 op2 dice3
其中:
- op1 和op2 可以是+、-、* 或/。例如。 op1 = + 和 op2 = /
- 骰子1、骰子2和骰子3可以是本轮掷出的数字的任意组合。一个骰子的值只能在计算中使用一次。
- 对于除法,除数必须是被除数的因数
- 可以添加括号来覆盖运算符op1的优先级
和op2。即 (dice1 op1 dice2) op2 dice3 或 dice1 op1 (dice2 op2 dice3)
您可以使用
nums = [34, 12, 6]
itertools.combinations_with_replacement(ops_lis, len(nums) - 1)
您可以使用以下方法获取操作数的所有排列:
itertools.permutations(nums)
然后您可以使用三个嵌套循环构建所有可能的表达式,并使用 eval() 计算表达式。
获取运算符的所有组合。
这是我的快速解决方案。
我正在使用 np.nan,它在任何计算后都将保持为 np.nan,因此我们可以识别不满足条件的组合。
import numpy as np
import itertools
def plus(a, b):
return a + b
def minus(a, b):
return a - b
def mult(a, b):
return a * b
def div(a, b):
if b!=0:
if a%b==0:
return a//b
return np.nan
def combinations(nums, funcs):
t = []
for i in range(len(nums)-1):
t.append(nums)
t.append(funcs)
t.append(nums)
return list(itertools.product(*t))
def solve(instance):
instance = list(instance)
for i in range(len(instance)//2):
b = instance.pop()
func = instance.pop()
a = instance.pop()
instance.append(func(a, b))
return instance[0]
def main():
a = [1, 3 ,4]
func = [plus, minus, mult, div]
combs = combinations(a, func)
solutions = [solve(i) for i in combs]
for i, j in zip(combs, solutions):
print(i, j)
if __name__ == "__main__":
main()
它是从右到左求解运算,但您可以根据需要更改求解函数。
这是一个解决方案,它使用 itertools
来生成两个运算符的每个组合,并使用 Python 的 eval
来评估字符串。
from itertools import product
ops = ['+', '-', '*', '/']
nums = [3, 4, 0]
combos = product(ops, repeat=2)
for expr in combos:
eval_me = f'{nums[0]} {expr[0]} {nums[1]} {expr[1]} {nums[2]}'
try:
result = eval(eval_me)
print (f'{eval_me} = {result}')
except ZeroDivisionError as e:
print (f'expression "{eval_me}" caused an exception: {e}')
使用 4 个运算符,我们有 4 * 4 = 16 个结果。
结果如下:
3 + 4 + 0 = 7
3 + 4 - 0 = 7
3 + 4 * 0 = 3
expression "3 + 4 / 0" caused an exception: division by zero
3 - 4 + 0 = -1
3 - 4 - 0 = -1
3 - 4 * 0 = 3
expression "3 - 4 / 0" caused an exception: division by zero
3 * 4 + 0 = 12
3 * 4 - 0 = 12
3 * 4 * 0 = 0
expression "3 * 4 / 0" caused an exception: division by zero
3 / 4 + 0 = 0.75
3 / 4 - 0 = 0.75
3 / 4 * 0 = 0.0
expression "3 / 4 / 0" caused an exception: float division by zero
要获得所有可能的结果,您需要在组合中包含操作分组。我建议为此使用递归函数:
def calcAll(*values,seen=None):
seen = seen or set()
if len(values) == 2:
a,b = values
a,sa = (a[0],f"({a[1]})") if isinstance(a,tuple) else (a,str(a))
b,sb = (b[0],f"({b[1]})") if isinstance(b,tuple) else (b,str(b))
if a>b : a,sa, b,sb = b,sb, a,sa
if (a,b) in seen or seen.add((a,b)) :return
yield a+b, f"{sa}+{sb}"
yield a*b, f"{sa}*{sb}"
yield a-b, f"{sa}-{sb}"
yield b-a, f"{sb}-{sa}"
if b != 0 and a%b==0: yield a//b, f"{sa}/{sb}"
if a != 0 and b%a==0: yield b//a, f"{sb}/{sa}"
return
pairs = ((i,j) for i in range(len(values)-1) for j in range(i+1,len(values)))
for i,j in pairs:
rest = [*values]
a,b = rest.pop(j),rest.pop(i)
for paired in calcAll(a,b,seen=seen):
for result in calcAll(paired,*rest):
if result in seen or seen.add(result): continue
yield result
输出:
# distinct positive solutions sorted by result
for r,sr in sorted(calcAll(3,4,1)):
if r>0: print(sr,"=",r)
(1*4)-3 = 1
4-(3/1) = 1
(4/1)-3 = 1
(4-3)*1 = 1
4/(1+3) = 1
4-(1*3) = 1
(4-3)/1 = 1
1/(4-3) = 1
3/(4-1) = 1
(1+3)/4 = 1
(4-1)/3 = 1
1-(3-4) = 2
4-(3-1) = 2
(1+4)-3 = 2
(1-3)+4 = 2
(4-3)+1 = 2
4/(3-1) = 2
(4-1)+3 = 6
(3-1)+4 = 6
3-(1-4) = 6
4-(1-3) = 6
(4+3)-1 = 6
(1*4)+3 = 7
(3/1)+4 = 7
(4/1)+3 = 7
(1*3)+4 = 7
(4+3)/1 = 7
(4+3)*1 = 7
(1+4)+3 = 8
(1+3)+4 = 8
(3-1)*4 = 8
(4+3)+1 = 8
(4-1)*3 = 9
(4*3)-1 = 11
(1*4)*3 = 12
(4*3)*1 = 12
(4*3)/1 = 12
(1*3)*4 = 12
(3/1)*4 = 12
(4/1)*3 = 12
(4*3)+1 = 13
(1+4)*3 = 15
(1+3)*4 = 16
如果您只想要明显的积极结果:
print( set(r for r,_ in calcAll(3,4,1) if r>0) )
{1, 2, 6, 7, 8, 9, 11, 12, 13, 15, 16}
该函数也适用于较大的数字列表:
# one solution for each positive result of operations between 4 numbers
for r,sr in sorted(dict(calcAll(1,2,3,4)).items()):
if r>0: print(sr,"=",r)
(2/1)+(3-4) = 1
(2-1)-(3-4) = 2
(2/1)-(3-4) = 3
(4*3)/(2+1) = 4
((4*3)/2)-1 = 5
(4*3)/(2/1) = 6
((4*3)/2)+1 = 7
(4+3)-(1-2) = 8
(4*3)-(2+1) = 9
(4*3)-(2/1) = 10
(1-2)+(4*3) = 11
(4*3)/(2-1) = 12
(4*3)-(1-2) = 13
(2/1)+(4*3) = 14
(2+1)+(4*3) = 15
(1+(4+3))*2 = 16
(3*(4+2))-1 = 17
(3/1)*(4+2) = 18
(3*(4+2))+1 = 19
((3*2)-1)*4 = 20
(2+1)*(4+3) = 21
((4*3)-1)*2 = 22
(2*(4*3))-1 = 23
(2/1)*(4*3) = 24
(2*(4*3))+1 = 25
(1+(4*3))*2 = 26
(1+(4*2))*3 = 27
(1+(3*2))*4 = 28
(4+1)*(3*2) = 30
(3+1)*(4*2) = 32
(2+1)*(4*3) = 36
还有重复的数字:
for r,sr in sorted(dict(calcAll(3,3,3)).items()):
if r>0: print(sr,"=",r)
3-(3/3) = 2
3/(3/3) = 3
(3/3)+3 = 4
(3*3)-3 = 6
(3+3)+3 = 9
(3*3)+3 = 12
(3+3)*3 = 18
(3*3)*3 = 27
假设我有三个整数。我想获得通过在它们之间执行所有 16(*, /, +, -
的 4x4)操作获得的所有可能值的列表。
就像我有 3 4 1
,我们应该得到值 1、2、6、7、8、9、11、12,
13、15和16。即
res = num1 (op1) num2 (op2) num3
其中运算符为:
["**", "*/", "*+", "*-", "/*", "//", "/+", "/-", "+*", "+/", "++", "+-", "-*", "-/", "-+", "--"]
However, the catch is that division can only be possible if
x%y==0
i.e. divisor is factor of dividend.
所以,到目前为止,我已经能够暴力破解每一个操作,但缺少一些答案。我还定义了一个自定义除法运算以考虑 捕获量。
我需要 return 一个包含所有正值的唯一值的列表。
我目前的代码很乱,但这是为了它。这也遗漏了一些值。
def div(x, y):
if x!=0 and y!=0:
if x%y==0:return x/y
else:return None
ops_lis = ["**", "*/", "*+", "*-", "/*", "//", "/+", "/-", "+*", "+/", "++", "+-", "-*", "-/", "-+", "--"]
d1, d2, d3 = map(int, input().split())
cal_lis, res_lis = [], []
for op in ops_lis:
if op[0] == "*" and op[1] == "*":cal_lis.append(d1*d2*d3)
if op[0] == "*" and op[1] == "/":
if div(d1*d2, d3) != None:cal_lis.append(div(d1*d2, d3))
cal_lis.append(div(d1*d2, d3))
if op[0] == "*" and op[1] == "+":
cal_lis.append(d1*(d2+d3))
cal_lis.append((d1*d2)+d3)
if op[0] == "*" and op[1] == "-":
cal_lis.append(d1*d2-d3)
cal_lis.append(d1*(d2-d3))
cal_lis.append((d1*d3)-d2)
if op[0] == "/" and op[1] == "*":cal_lis.append(div(d1, d2*d3))
if op[0] == "/" and op[1] == "/":
if div(d1, d2) == None or div(d2, d3) == None:
cal_lis.append(None)
else:
cal_lis.append(div(div(d1, d2), d3))
if op[0] == "/" and op[1] == "+":
if div(d1, d2) == None:
cal_lis.append(None)
else:
cal_lis.append(div(d1, d2)+d3)
if op[0] == "/" and op[1] == "-":
if div(d1, d2) == None:
cal_lis.append(None)
else:
cal_lis.append(div(d1, d2)-d3)
if op[0] == "+" and op[1] == "*":
cal_lis.append(d1+d2*d3)
cal_lis.append((d1+d2)*d3)
cal_lis.append((d1+d3)*d2)
if op[0] == "+" and op[1] == "/":
if div(d2, d3) == None:
cal_lis.append(None)
else:
cal_lis.append(d1+div(d2, d3))
if op[0] == "+" and op[1] == "+":cal_lis.append(d1+d2+d3)
if op[0] == "+" and op[1] == "-":cal_lis.append(d1+d2-d3)
if op[0] == "-" and op[1] == "*":
cal_lis.append(d1-d2*d3)
cal_lis.append((d1-d2)*d3)
cal_lis.append((d1-d3)*d2)
if op[0] == "-" and op[1] == "/":
if div(d2, d3) == None:cal_lis.append(None)
else: cal_lis.append(d1-div(d2, d3))
if div(d1-d2, d3) == None:cal_lis.append(None)
else: cal_lis.append(div(d1-d2, d3))
if op[0] == "-" and op[1] == "+":cal_lis.append(d1-d2+d3)
if op[0] == "-" and op[1] == "-":cal_lis.append(d1-d2-d3)
# print(cal_lis)
cal_lis = [int(cal) for cal in cal_lis if cal!=None]
for res in cal_lis:
if (res > 0 and res not in res_lis):
res_lis.append(int(res))
for a in sorted(res_lis):
print(a, end=" ")
print()
鉴于划分条件也为真,是否有一种有效的方法来执行此任务(也许使用树?)?
如有任何帮助,我们将不胜感激...
编辑:添加约束
计算必须符合以下格式: number = dice1 op1 dice2 op2 dice3
其中:
- op1 和op2 可以是+、-、* 或/。例如。 op1 = + 和 op2 = /
- 骰子1、骰子2和骰子3可以是本轮掷出的数字的任意组合。一个骰子的值只能在计算中使用一次。
- 对于除法,除数必须是被除数的因数
- 可以添加括号来覆盖运算符op1的优先级 和op2。即 (dice1 op1 dice2) op2 dice3 或 dice1 op1 (dice2 op2 dice3)
您可以使用
nums = [34, 12, 6]
itertools.combinations_with_replacement(ops_lis, len(nums) - 1)
您可以使用以下方法获取操作数的所有排列:
itertools.permutations(nums)
然后您可以使用三个嵌套循环构建所有可能的表达式,并使用 eval() 计算表达式。
获取运算符的所有组合。
这是我的快速解决方案。 我正在使用 np.nan,它在任何计算后都将保持为 np.nan,因此我们可以识别不满足条件的组合。
import numpy as np
import itertools
def plus(a, b):
return a + b
def minus(a, b):
return a - b
def mult(a, b):
return a * b
def div(a, b):
if b!=0:
if a%b==0:
return a//b
return np.nan
def combinations(nums, funcs):
t = []
for i in range(len(nums)-1):
t.append(nums)
t.append(funcs)
t.append(nums)
return list(itertools.product(*t))
def solve(instance):
instance = list(instance)
for i in range(len(instance)//2):
b = instance.pop()
func = instance.pop()
a = instance.pop()
instance.append(func(a, b))
return instance[0]
def main():
a = [1, 3 ,4]
func = [plus, minus, mult, div]
combs = combinations(a, func)
solutions = [solve(i) for i in combs]
for i, j in zip(combs, solutions):
print(i, j)
if __name__ == "__main__":
main()
它是从右到左求解运算,但您可以根据需要更改求解函数。
这是一个解决方案,它使用 itertools
来生成两个运算符的每个组合,并使用 Python 的 eval
来评估字符串。
from itertools import product
ops = ['+', '-', '*', '/']
nums = [3, 4, 0]
combos = product(ops, repeat=2)
for expr in combos:
eval_me = f'{nums[0]} {expr[0]} {nums[1]} {expr[1]} {nums[2]}'
try:
result = eval(eval_me)
print (f'{eval_me} = {result}')
except ZeroDivisionError as e:
print (f'expression "{eval_me}" caused an exception: {e}')
使用 4 个运算符,我们有 4 * 4 = 16 个结果。
结果如下:
3 + 4 + 0 = 7
3 + 4 - 0 = 7
3 + 4 * 0 = 3
expression "3 + 4 / 0" caused an exception: division by zero
3 - 4 + 0 = -1
3 - 4 - 0 = -1
3 - 4 * 0 = 3
expression "3 - 4 / 0" caused an exception: division by zero
3 * 4 + 0 = 12
3 * 4 - 0 = 12
3 * 4 * 0 = 0
expression "3 * 4 / 0" caused an exception: division by zero
3 / 4 + 0 = 0.75
3 / 4 - 0 = 0.75
3 / 4 * 0 = 0.0
expression "3 / 4 / 0" caused an exception: float division by zero
要获得所有可能的结果,您需要在组合中包含操作分组。我建议为此使用递归函数:
def calcAll(*values,seen=None):
seen = seen or set()
if len(values) == 2:
a,b = values
a,sa = (a[0],f"({a[1]})") if isinstance(a,tuple) else (a,str(a))
b,sb = (b[0],f"({b[1]})") if isinstance(b,tuple) else (b,str(b))
if a>b : a,sa, b,sb = b,sb, a,sa
if (a,b) in seen or seen.add((a,b)) :return
yield a+b, f"{sa}+{sb}"
yield a*b, f"{sa}*{sb}"
yield a-b, f"{sa}-{sb}"
yield b-a, f"{sb}-{sa}"
if b != 0 and a%b==0: yield a//b, f"{sa}/{sb}"
if a != 0 and b%a==0: yield b//a, f"{sb}/{sa}"
return
pairs = ((i,j) for i in range(len(values)-1) for j in range(i+1,len(values)))
for i,j in pairs:
rest = [*values]
a,b = rest.pop(j),rest.pop(i)
for paired in calcAll(a,b,seen=seen):
for result in calcAll(paired,*rest):
if result in seen or seen.add(result): continue
yield result
输出:
# distinct positive solutions sorted by result
for r,sr in sorted(calcAll(3,4,1)):
if r>0: print(sr,"=",r)
(1*4)-3 = 1
4-(3/1) = 1
(4/1)-3 = 1
(4-3)*1 = 1
4/(1+3) = 1
4-(1*3) = 1
(4-3)/1 = 1
1/(4-3) = 1
3/(4-1) = 1
(1+3)/4 = 1
(4-1)/3 = 1
1-(3-4) = 2
4-(3-1) = 2
(1+4)-3 = 2
(1-3)+4 = 2
(4-3)+1 = 2
4/(3-1) = 2
(4-1)+3 = 6
(3-1)+4 = 6
3-(1-4) = 6
4-(1-3) = 6
(4+3)-1 = 6
(1*4)+3 = 7
(3/1)+4 = 7
(4/1)+3 = 7
(1*3)+4 = 7
(4+3)/1 = 7
(4+3)*1 = 7
(1+4)+3 = 8
(1+3)+4 = 8
(3-1)*4 = 8
(4+3)+1 = 8
(4-1)*3 = 9
(4*3)-1 = 11
(1*4)*3 = 12
(4*3)*1 = 12
(4*3)/1 = 12
(1*3)*4 = 12
(3/1)*4 = 12
(4/1)*3 = 12
(4*3)+1 = 13
(1+4)*3 = 15
(1+3)*4 = 16
如果您只想要明显的积极结果:
print( set(r for r,_ in calcAll(3,4,1) if r>0) )
{1, 2, 6, 7, 8, 9, 11, 12, 13, 15, 16}
该函数也适用于较大的数字列表:
# one solution for each positive result of operations between 4 numbers
for r,sr in sorted(dict(calcAll(1,2,3,4)).items()):
if r>0: print(sr,"=",r)
(2/1)+(3-4) = 1
(2-1)-(3-4) = 2
(2/1)-(3-4) = 3
(4*3)/(2+1) = 4
((4*3)/2)-1 = 5
(4*3)/(2/1) = 6
((4*3)/2)+1 = 7
(4+3)-(1-2) = 8
(4*3)-(2+1) = 9
(4*3)-(2/1) = 10
(1-2)+(4*3) = 11
(4*3)/(2-1) = 12
(4*3)-(1-2) = 13
(2/1)+(4*3) = 14
(2+1)+(4*3) = 15
(1+(4+3))*2 = 16
(3*(4+2))-1 = 17
(3/1)*(4+2) = 18
(3*(4+2))+1 = 19
((3*2)-1)*4 = 20
(2+1)*(4+3) = 21
((4*3)-1)*2 = 22
(2*(4*3))-1 = 23
(2/1)*(4*3) = 24
(2*(4*3))+1 = 25
(1+(4*3))*2 = 26
(1+(4*2))*3 = 27
(1+(3*2))*4 = 28
(4+1)*(3*2) = 30
(3+1)*(4*2) = 32
(2+1)*(4*3) = 36
还有重复的数字:
for r,sr in sorted(dict(calcAll(3,3,3)).items()):
if r>0: print(sr,"=",r)
3-(3/3) = 2
3/(3/3) = 3
(3/3)+3 = 4
(3*3)-3 = 6
(3+3)+3 = 9
(3*3)+3 = 12
(3+3)*3 = 18
(3*3)*3 = 27