python - 如何在转换后找到两个等价的表达式(例如交换律等)
问题描述
我正在为我的表弟制作一个 24 分的游戏,我设计的程序是为给定的四个或五个数字输出所有可能的解决方案。底层机制基本上是找到所有可能的括号位置并拟合数字以查看结果是否为 24。程序现在能够找到所有答案,但存在一个大问题。
例如,给定数字
3,3,6,7,9
一个可能的答案是
3*((9+7)/6*3)
但是,该程序也会给出类似的答案
3*(9+7)/(6/3)
3*((9+7)/(6/3))
这些实际上是等价的方程式,不应被视为不同的答案。通过删除所有包含“+(”、“-(”、“)-”、“)+”和“)*”的答案,我设法消除了一些等价的答案。有什么办法可以消除所有等价的表达式?谢谢!
我在下面附上了我当前的代码。
from itertools import permutations
while True:
numnum = input('Please choose number of cards (enter anything other than 4 and 5 to quit the program):')
if numnum == '4':
try:
a = int(input("Please enter the first number:"))
b = int(input("Please enter the second number:"))
c = int(input("Please enter the third number:"))
d = int(input("Please enter the fourth number:"))
except:
print('WARNING: Please enter a real number!')
continue
print('Processing...')
my_list = [a, b, c, d]
# Randomly arrange a list of 4 integers
result = [c for c in permutations(my_list, 4)]
symbols = ["+", "-", "*", "/"]
list2 = [] # Calculate the list of 24 permutations and combinations
flag = False
for one, two, three, four in result:
for s1 in symbols:
for s2 in symbols:
for s3 in symbols:
if s1 + s2 + s3 in ['+++', '***', '+--', '++-', '**/', '*//', '///']:
express = ["{0}{1}{2}{3}{4}{5}{6}".format(one, s1, two, s2, three, s3, four)]
elif s1 + s2 + s3 in ['+-+', '-++', '-+-', '--+', '*/*', '/**', '/*/', '//*']:
continue
else:
express = ["({0}{1}{2}){3}{4}{5}{6}".format(one, s1, two, s2, three, s3, four),
"({0}{1}{2}{3}{4}){5}{6}".format(one, s1, two, s2, three, s3, four),
"{0}{1}({2}{3}{4}){5}{6}".format(one, s1, two, s2, three, s3, four),
"{0}{1}({2}{3}{4}{5}{6})".format(one, s1, two, s2, three, s3, four),
"{0}{1}{2}{3}({4}{5}{6})".format(one, s1, two, s2, three, s3, four),
"(({0}{1}{2}){3}{4}){5}{6}".format(one, s1, two, s2, three, s3, four),
"({0}{1}{2}){3}({4}{5}{6})".format(one, s1, two, s2, three, s3, four),
"({0}{1}({2}{3}{4})){5}{6}".format(one, s1, two, s2, three, s3, four),
"{0}{1}(({2}{3}{4}){5}{6})".format(one, s1, two, s2, three, s3, four),
"{0}{1}({2}{3}({4}{5}{6}))".format(one, s1, two, s2, three, s3, four)]
for e in express:
try:
if eval(e) == 24:
list2.append(e)
flag = True
except ZeroDivisionError:
pass
for c in list2:
if '+(' in c or '-(' in c or ')-' in c or ')+' in c or ')*' in c:
continue
print(c)
if not flag:
print("NO solution...")
elif numnum == '5':
try:
a = int(input("Please enter the first number:"))
b = int(input("Please enter the second number:"))
c = int(input("Please enter the third number:"))
d = int(input("Please enter the fourth number:"))
e = int(input('Please enter the fifth number:'))
except:
print('WARNING: Please enter a real number!')
continue
print('Processing...')
my_list = [a, b, c, d, e]
# Randomly arrange a list of 4 integers
result = [c for c in permutations(my_list, 5)]
symbols = ["+", "-", "*", "/"]
list2 = [] # Calculate the list of 24 permutations and combinations
flag = False
for one, two, three, four, five in result:
for s1 in symbols:
for s2 in symbols:
for s3 in symbols:
for s4 in symbols:
if s1 + s2 + s3 + s4 in ['++++', '****', '+---', '+++-', '++--', '**//', '*///', '///',
'***/']:
express = ["{0}{1}{2}{3}{4}{5}{6}{7}{8}".format(one, s1, two, s2, three, s3, four, s4, five)]
elif (s1, s2, s3, s4) in permutations(['*', '/', '/', '/']) \
or (s1, s2, s3, s4) in permutations(['*', '*', '/', '/']) \
or (s1, s2, s3, s4) in permutations(['*', '*', '*', '/']) \
or (s1, s2, s3, s4) in permutations(['+', '-', '-', '-']) \
or (s1, s2, s3, s4) in permutations(['+', '+', '-', '-']) \
or (s1, s2, s3, s4) in permutations(['+', '+', '+', '-']):
continue
else:
express = ["({0}{1}{2}){3}{4}{5}{6}{7}{8}".format(one, s1, two, s2, three, s3, four, s4, five),
"({0}{1}{2}{3}{4}){5}{6}{7}{8}".format(one, s1, two, s2, three, s3, four, s4, five),
"({0}{1}{2}{3}{4}{5}{6}){7}{8}".format(one, s1, two, s2, three, s3, four, s4, five),
"{0}{1}({2}{3}{4}){5}{6}{7}{8}".format(one, s1, two, s2, three, s3, four, s4, five),
"{0}{1}({2}{3}{4}{5}{6}){7}{8}".format(one, s1, two, s2, three, s3, four, s4, five),
"{0}{1}({2}{3}{4}{5}{6}{7}{8})".format(one, s1, two, s2, three, s3, four, s4, five),
"{0}{1}{2}{3}({4}{5}{6}){7}{8}".format(one, s1, two, s2, three, s3, four, s4, five),
"{0}{1}{2}{3}({4}{5}{6}{7}{8})".format(one, s1, two, s2, three, s3, four, s4, five),
"{0}{1}{2}{3}{4}{5}({6}{7}{8})".format(one, s1, two, s2, three, s3, four, s4, five),
"(({0}{1}{2}){3}{4}){5}{6}{7}{8}".format(one, s1, two, s2, three, s3, four, s4, five),
"(({0}{1}{2}){3}{4}{5}{6}){7}{8}".format(one, s1, two, s2, three, s3, four, s4, five),
"({0}{1}{2}){3}({4}{5}{6}){7}{8}".format(one, s1, two, s2, three, s3, four, s4, five),
"({0}{1}{2}){3}({4}{5}{6}{7}{8})".format(one, s1, two, s2, three, s3, four, s4, five),
"({0}{1}{2}){3}{4}{5}({6}{7}{8})".format(one, s1, two, s2, three, s3, four, s4, five),
"({0}{1}{2}{3}{4}){5}({6}{7}{8})".format(one, s1, two, s2, three, s3, four, s4, five),
"(({0}{1}{2}{3}{4}){5}{6}){7}{8}".format(one, s1, two, s2, three, s3, four, s4, five),
"({0}{1}({2}{3}{4})){5}{6}{7}{8}".format(one, s1, two, s2, three, s3, four, s4, five),
"({0}{1}({2}{3}{4}){5}{6}){7}{8}".format(one, s1, two, s2, three, s3, four, s4, five),
"({0}{1}{2}{3}({4}{5}{6})){7}{8}".format(one, s1, two, s2, three, s3, four, s4, five),
"({0}{1}({2}{3}{4}{5}{6})){7}{8}".format(one, s1, two, s2, three, s3, four, s4, five),
"{0}{1}(({2}{3}{4}){5}{6}){7}{8}".format(one, s1, two, s2, three, s3, four, s4, five),
"{0}{1}(({2}{3}{4}){5}{6}{7}{8})".format(one, s1, two, s2, three, s3, four, s4, five),
"{0}{1}({2}{3}{4}){5}({6}{7}{8})".format(one, s1, two, s2, three, s3, four, s4, five),
"{0}{1}({2}{3}({4}{5}{6})){7}{8}".format(one, s1, two, s2, three, s3, four, s4, five),
"{0}{1}(({2}{3}{4}{5}{6}){7}{8})".format(one, s1, two, s2, three, s3, four, s4, five),
"{0}{1}({2}{3}({4}{5}{6}){7}{8})".format(one, s1, two, s2, three, s3, four, s4, five),
"{0}{1}({2}{3}({4}{5}{6}{7}{8}))".format(one, s1, two, s2, three, s3, four, s4, five),
"{0}{1}({2}{3}{4}{5}({6}{7}{8}))".format(one, s1, two, s2, three, s3, four, s4, five),
"{0}{1}{2}{3}(({4}{5}{6}){7}{8})".format(one, s1, two, s2, three, s3, four, s4, five),
"{0}{1}{2}{3}({4}{5}({6}{7}{8}))".format(one, s1, two, s2, three, s3, four, s4, five),
"((({0}{1}{2}){3}{4}){5}{6}){7}{8}".format(one, s1, two, s2, three, s3, four, s4, five),
"(({0}{1}{2}){3}({4}{5}{6})){7}{8}".format(one, s1, two, s2, three, s3, four, s4, five),
"({0}{1}{2}){3}(({4}{5}{6}){7}{8})".format(one, s1, two, s2, three, s3, four, s4, five),
"({0}{1}{2}){3}({4}{5}({6}{7}{8}))".format(one, s1, two, s2, three, s3, four, s4, five),
"(({0}{1}({2}{3}{4})){5}{6}){7}{8}".format(one, s1, two, s2, three, s3, four, s4, five),
"({0}{1}({2}{3}{4})){5}({6}{7}{8})".format(one, s1, two, s2, three, s3, four, s4, five),
"({0}{1}(({2}{3}{4}){5}{6})){7}{8}".format(one, s1, two, s2, three, s3, four, s4, five),
"({0}{1}({2}{3}({4}{5}{6}))){7}{8}".format(one, s1, two, s2, three, s3, four, s4, five),
"{0}{1}((({2}{3}{4}){5}{6}){7}{8})".format(one, s1, two, s2, three, s3, four, s4, five),
"{0}{1}(({2}{3}{4}){5}({6}{7}{8}))".format(one, s1, two, s2, three, s3, four, s4, five),
"{0}{1}(({2}{3}({4}{5}{6})){7}{8})".format(one, s1, two, s2, three, s3, four, s4, five),
"{0}{1}({2}{3}(({4}{5}{6}){7}{8}))".format(one, s1, two, s2, three, s3, four, s4, five),
"{0}{1}({2}{3}({4}{5}({6}{7}{8})))".format(one, s1, two, s2, three, s3, four, s4, five)]
for e in express:
try:
if eval(e) == 24:
list2.append(e)
flag = True
except ZeroDivisionError:
pass
for c in list2:
if '+(' in c or '-(' in c or ')-' in c or ')+' in c or ')*' in c:
continue
print(c)
if not flag:
print("NO solution...")
else:
break
解决方案
你试过使用eval()
吗?
for i, e1 in sorted(enumerate(express), reverse=True): # reversed and enumerate so we can remove during iteration by popping an index
for n, e2 in sorted(enumerate(express), reverse=True):
if e1 != e2: # checks that it isn't comparing against itself as a string
if eval(e1) == eval(e2):
express.pop(n)
eval()
可预测地评估字符串文字中任何表达式的值。添加上面的内容应该检查express
列表中的每个表达式,并将其与其他所有表达式进行检查。
关于使用反向枚举列表:这是一种允许您在列表迭代期间从列表中删除元素的方法。enumerate()
在 ing 之前,它会为您提供原始列表中项目的索引sorted(reverse=True)
。您将其反转,以便如果从原始列表中删除一个项目,则它之前的所有项目的索引都不会受到影响。
编辑:澄清和标记
推荐阅读
- ajax - 如何使用 AJax 从表的行(循环)中获取无格式数据以更新列(通过
- javascript - 为什么重新分配 __proto__ 会返回不同的结果?
- excel - Excel VBA“Selection.Left”
- java - 无法为 Java 运行 vscode 调试器
- reactjs - 请确保您尝试使用的元素仍然已安装
- php - 在 symfony 2.8 中,这两个命令都不能在 app/console 上运行
- javascript - xhttp.onreadystatechange setInterval 函数中未捕获的 TypeError innerHTML of null
- asp.net-core - 在 asp.net core blazor 应用程序中使用 JWT 身份验证 API
- node.js - 如何修复 yarn.lock 和 package-lock json mix
- reactjs - Okta 重定向因 React HashRouter 而失败