繁体   English   中英

与用户输入最接近的数字

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM