[英]Closest to a number from user inputs
因此,我想知道是否有可能从用户那里获取3个数字,范围均为1-6,并从用户那里获取1个其他输入,范围为1-144,并制作一个程序,该程序将获取您获得的前3个数字并找到一个使用加法,减法,乘法,除法,求根和幂的方法,使用3个数字来找到第4个用户输入的方法。 如果您无法获得第4个用户输入,请从前3个输入中找到最接近的输入,然后程序应告诉您使用的操作以及使用的编号。 这基本上是在重新创建游戏ThinkFun Math Dice。
例如:如果用户输入的前3个数字是5、2和9,第4个数字是86,则程序应执行9 ^ 2(即81)和81 + 5(即86)。在另一种情况下,如果3个数字是6、4和2,最终答案是(第4个输入)24,程序应该执行6 * 4 -2或6 * 4 +2或4 ^ 2 + 6,因为它们全部等于26或22不可能获得24。
问题的核心是决定使用哪种格式来写出可能的计算,列出它们,尝试每一种,然后选择最佳的。
我将建议使用RPN表示法,因为它很容易使用。 我给了您代码,以RPN表示法列出了可能的计算。 您仍然需要执行IO并编写RPN计算器。 IO很简单。 您可以在线学习很多RPN计算器示例。
def list_perms (args):
if 0 == len(args):
yield []
else:
x = args[0]
for p in list_perms(args[1:]):
for i in range(0, len(p)+1):
yield p[:i] + [x] + p[i:]
def list_rpn (x, y, z):
ops = ['+', '-', '*', '/', '^', 'r']
for p in list_perms([x, y, z]):
for op1 in ops:
for op2 in ops:
yield p + [op1, op2]
yield p[0:2] + [op1, p[2], op2]
def evaluate (calc):
return 'you have to figure this out'
def find_best (x, y, z, r):
best_val = x+y+z
best_calc = [x, y, z, '+', '+']
for calc in list_rpn(5, 6, 8):
try:
val = evaluate(calc)
if val == r:
return calc
elif abs(val - r) < abs(best_val - r):
best_val = val
best_calc = calc
except Exception:
# Throw exceptions on things like divide by 0, or powers of
# negative numbers that aren't n or 1/n where n is an odd number
pass
return best_calc
# You should also do proper IO here.
print(find_best(5, 2, 9, 24))
尽管btilly的答案是绝对正确的,但它至少比python中的问题要解决的要多。 使用itertools库和eval()
函数,您可以得到一种更短,更简单的方法。 请注意eval()
和exec()
被认为是不安全的,因为它们将执行传递的所有内容,但是作为个人使用的脚本应该没问题。 任何恶意代码很可能都会触发将输入强制转换为int的异常。 从itertools导入排列
coeffs = list(map(int, input("Coefficents, separated by spaces:\n").split()))
target = int(input("Target value:\n"))
operators = ["({}+{})","({}-{})","({}*{})","({}/{})","({}**{})","({}**(1.0/{}))"]
def make_expr(expr, coeffs, target):
if not coeffs:
try:
return eval(expr), expr
except OverflowError:
return None
except ArithmeticError:
return None
solutions = [make_expr(op.format(expr, coeffs[0]), coeffs[1:], target) for op in operators]
solutions += [make_expr(op.format(coeffs[0], expr), coeffs[1:], target) for op in operators]
solutions = [x for x in solutions if x is not None]
val, expr = min(solutions, key=lambda x: abs(x[0]-target))
return val, expr
def find_best(coeffs, target):
assert(len(coeffs) > 1)
solutions = [make_expr(perm[0], perm[1:], target) for perm in permutations(coeffs)]
solutions = [x for x in solutions if x is not None]
val, expr = min(solutions, key=lambda x: abs(x[0]-target))
return "Closest value: {0}\nExpression: {1}".format(val, expr)
print(find_best(coeffs, target))
要支持更多运算符,只需将其插入列表中,并在参数中加上{}
并用parethese括起来。 我增加了对额外运算符的支持,但是由于在找到完美解决方案时我不会缩短迭代过程,因此3个以上的运算符可能需要很长时间。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.