Algorithm 给定5个数字,仅使用加法、乘法和减法检查是否可以生成42?

Algorithm 给定5个数字,仅使用加法、乘法和减法检查是否可以生成42?,algorithm,Algorithm,给定5个介于1-52之间的数字,检查是否可以使用加法、乘法和减法运算生成42。您可以多次使用这些操作。 我在一次在线测试中遇到了这个问题,但无法回答。假设每个数字只能使用一次,并且只有五个数字和三个操作,你可以用蛮力的方法很容易地做到这一点 它只需检查5*3*4*3*3*3*2*3*1,或大约10000潜在解决方案 作为概念证明,这里有一个用于执行此操作的Python程序: import sys import itertools if len(sys.argv) != 6: print

给定5个介于1-52之间的数字,检查是否可以使用加法、乘法和减法运算生成42。您可以多次使用这些操作。 我在一次在线测试中遇到了这个问题,但无法回答。

假设每个数字只能使用一次,并且只有五个数字和三个操作,你可以用蛮力的方法很容易地做到这一点

它只需检查
5*3*4*3*3*3*2*3*1
,或大约
10000
潜在解决方案

作为概念证明,这里有一个用于执行此操作的Python程序:

import sys
import itertools

if len(sys.argv) != 6:
    print "Usage: testprog.py <num1> <num2> <num3> <num4> <num5>"
    sys.exit(1)

ops = ['+', '-', '*']
nums = []
for num in sys.argv[1:]:
    nums.append(num)

for p in itertools.permutations(nums,len(nums)):
    for op1 in ops:
        for op2 in ops:
            for op3 in ops:
                for op4 in ops:
                    expr = p[0] + op1 + p[1] + op2 + p[2] + op3 + p[3] + op4 + p[4]
                    result = eval(expr)
                    if result == 42:
                        print expr, '=', result
您可以看到,它大约在五分之一秒(在我的盒子上)内完成。

假设每个数字只使用一次,并且只使用五个数字和三个操作,您可以非常轻松地使用蛮力方法来完成

它只需检查
5*3*4*3*3*3*2*3*1
,或大约
10000
潜在解决方案

作为概念证明,这里有一个用于执行此操作的Python程序:

import sys
import itertools

if len(sys.argv) != 6:
    print "Usage: testprog.py <num1> <num2> <num3> <num4> <num5>"
    sys.exit(1)

ops = ['+', '-', '*']
nums = []
for num in sys.argv[1:]:
    nums.append(num)

for p in itertools.permutations(nums,len(nums)):
    for op1 in ops:
        for op2 in ops:
            for op3 in ops:
                for op4 in ops:
                    expr = p[0] + op1 + p[1] + op2 + p[2] + op3 + p[3] + op4 + p[4]
                    result = eval(expr)
                    if result == 42:
                        print expr, '=', result
您可以看到,它大约在五分之一秒(在我的盒子上)内完成。

假设每个数字只使用一次,并且只使用五个数字和三个操作,您可以非常轻松地使用蛮力方法来完成

它只需检查
5*3*4*3*3*3*2*3*1
,或大约
10000
潜在解决方案

作为概念证明,这里有一个用于执行此操作的Python程序:

import sys
import itertools

if len(sys.argv) != 6:
    print "Usage: testprog.py <num1> <num2> <num3> <num4> <num5>"
    sys.exit(1)

ops = ['+', '-', '*']
nums = []
for num in sys.argv[1:]:
    nums.append(num)

for p in itertools.permutations(nums,len(nums)):
    for op1 in ops:
        for op2 in ops:
            for op3 in ops:
                for op4 in ops:
                    expr = p[0] + op1 + p[1] + op2 + p[2] + op3 + p[3] + op4 + p[4]
                    result = eval(expr)
                    if result == 42:
                        print expr, '=', result
您可以看到,它大约在五分之一秒(在我的盒子上)内完成。

假设每个数字只使用一次,并且只使用五个数字和三个操作,您可以非常轻松地使用蛮力方法来完成

它只需检查
5*3*4*3*3*3*2*3*1
,或大约
10000
潜在解决方案

作为概念证明,这里有一个用于执行此操作的Python程序:

import sys
import itertools

if len(sys.argv) != 6:
    print "Usage: testprog.py <num1> <num2> <num3> <num4> <num5>"
    sys.exit(1)

ops = ['+', '-', '*']
nums = []
for num in sys.argv[1:]:
    nums.append(num)

for p in itertools.permutations(nums,len(nums)):
    for op1 in ops:
        for op2 in ops:
            for op3 in ops:
                for op4 in ops:
                    expr = p[0] + op1 + p[1] + op2 + p[2] + op3 + p[3] + op4 + p[4]
                    result = eval(expr)
                    if result == 42:
                        print expr, '=', result
您可以看到它在大约五分之一秒(在我的盒子上)内完成。

假设:

  • 任何数字都可以多次使用
  • 操作立即完成(无运算符优先级)
在图形上执行广度优先搜索

from collections import defaultdict

def add(lhs, rhs):
    return lhs+rhs

def sub(lhs, rhs):
    return lhs-rhs

def mul(lhs, rhs):
    return lhs*rhs

ops = [add, sub, mul]   #allowed operations

graph = { 0:["0"]}      #graph key is node(number); value is a list of shortest paths to this node 
numbers=[1,2,3]         #allowed numbers in operations
target=12               #target node(number) 
gv_edges=[]             #edges for optional graphviz output 

#breadth first search until target is met
while not target in graph:
    new_graph=defaultdict(list, graph)
    for key in graph:
        #inefficiently searches old nodes also
        for n in numbers:
            for op in ops:
                newkey = op(key, n)
                if newkey not in graph:
                    #not met in previous iterations, keep new edge
                    newvals = ["{} --{}({})--> {}".format(val, op.__name__, n, newkey) for val in new_graph[key]]
                    new_graph[newkey].extend(newvals)    
                    gv_edges.append('"{}" -> "{}" [label="{}({})"]'.format(key, newkey, op.__name__, n))
                else:
                    #already met in previous iterations (shorter paths), do not keep new
                    pass
    graph=dict(new_graph)


#print all solutions
print "Solutions:"
print
for val in graph[target]:
    print val
print
print

#print optional graphviz digraph
gv_digraph='digraph {{ rankdir=LR ranksep=2\n"{}" [color=green style=filled fillcolor=green]\n{}\n}}'.format(target,"\n".join(gv_edges))
print "Graphviz Digraph for paste into http://stamm-wilbrandt.de/GraphvizFiddle/"
print "do this for reasonable number of edges only"
print
print gv_digraph
产生以下解决方案:

0 --add(1)--> 1 --add(3)--> 4 --mul(3)--> 12
0 --add(2)--> 2 --add(2)--> 4 --mul(3)--> 12
0 --add(2)--> 2 --mul(2)--> 4 --mul(3)--> 12
0 --add(3)--> 3 --add(1)--> 4 --mul(3)--> 12
0 --add(2)--> 2 --mul(3)--> 6 --mul(2)--> 12
0 --add(3)--> 3 --mul(2)--> 6 --mul(2)--> 12
0 --add(3)--> 3 --add(3)--> 6 --mul(2)--> 12
0 --add(3)--> 3 --mul(3)--> 9 --add(3)--> 12
深度3的完整图形(仅最短路径!)如下所示 假设:

  • 任何数字都可以多次使用
  • 操作立即完成(无运算符优先级)
在图形上执行广度优先搜索

from collections import defaultdict

def add(lhs, rhs):
    return lhs+rhs

def sub(lhs, rhs):
    return lhs-rhs

def mul(lhs, rhs):
    return lhs*rhs

ops = [add, sub, mul]   #allowed operations

graph = { 0:["0"]}      #graph key is node(number); value is a list of shortest paths to this node 
numbers=[1,2,3]         #allowed numbers in operations
target=12               #target node(number) 
gv_edges=[]             #edges for optional graphviz output 

#breadth first search until target is met
while not target in graph:
    new_graph=defaultdict(list, graph)
    for key in graph:
        #inefficiently searches old nodes also
        for n in numbers:
            for op in ops:
                newkey = op(key, n)
                if newkey not in graph:
                    #not met in previous iterations, keep new edge
                    newvals = ["{} --{}({})--> {}".format(val, op.__name__, n, newkey) for val in new_graph[key]]
                    new_graph[newkey].extend(newvals)    
                    gv_edges.append('"{}" -> "{}" [label="{}({})"]'.format(key, newkey, op.__name__, n))
                else:
                    #already met in previous iterations (shorter paths), do not keep new
                    pass
    graph=dict(new_graph)


#print all solutions
print "Solutions:"
print
for val in graph[target]:
    print val
print
print

#print optional graphviz digraph
gv_digraph='digraph {{ rankdir=LR ranksep=2\n"{}" [color=green style=filled fillcolor=green]\n{}\n}}'.format(target,"\n".join(gv_edges))
print "Graphviz Digraph for paste into http://stamm-wilbrandt.de/GraphvizFiddle/"
print "do this for reasonable number of edges only"
print
print gv_digraph
产生以下解决方案:

0 --add(1)--> 1 --add(3)--> 4 --mul(3)--> 12
0 --add(2)--> 2 --add(2)--> 4 --mul(3)--> 12
0 --add(2)--> 2 --mul(2)--> 4 --mul(3)--> 12
0 --add(3)--> 3 --add(1)--> 4 --mul(3)--> 12
0 --add(2)--> 2 --mul(3)--> 6 --mul(2)--> 12
0 --add(3)--> 3 --mul(2)--> 6 --mul(2)--> 12
0 --add(3)--> 3 --add(3)--> 6 --mul(2)--> 12
0 --add(3)--> 3 --mul(3)--> 9 --add(3)--> 12
深度3的完整图形(仅最短路径!)如下所示 假设:

  • 任何数字都可以多次使用
  • 操作立即完成(无运算符优先级)
在图形上执行广度优先搜索

from collections import defaultdict

def add(lhs, rhs):
    return lhs+rhs

def sub(lhs, rhs):
    return lhs-rhs

def mul(lhs, rhs):
    return lhs*rhs

ops = [add, sub, mul]   #allowed operations

graph = { 0:["0"]}      #graph key is node(number); value is a list of shortest paths to this node 
numbers=[1,2,3]         #allowed numbers in operations
target=12               #target node(number) 
gv_edges=[]             #edges for optional graphviz output 

#breadth first search until target is met
while not target in graph:
    new_graph=defaultdict(list, graph)
    for key in graph:
        #inefficiently searches old nodes also
        for n in numbers:
            for op in ops:
                newkey = op(key, n)
                if newkey not in graph:
                    #not met in previous iterations, keep new edge
                    newvals = ["{} --{}({})--> {}".format(val, op.__name__, n, newkey) for val in new_graph[key]]
                    new_graph[newkey].extend(newvals)    
                    gv_edges.append('"{}" -> "{}" [label="{}({})"]'.format(key, newkey, op.__name__, n))
                else:
                    #already met in previous iterations (shorter paths), do not keep new
                    pass
    graph=dict(new_graph)


#print all solutions
print "Solutions:"
print
for val in graph[target]:
    print val
print
print

#print optional graphviz digraph
gv_digraph='digraph {{ rankdir=LR ranksep=2\n"{}" [color=green style=filled fillcolor=green]\n{}\n}}'.format(target,"\n".join(gv_edges))
print "Graphviz Digraph for paste into http://stamm-wilbrandt.de/GraphvizFiddle/"
print "do this for reasonable number of edges only"
print
print gv_digraph
产生以下解决方案:

0 --add(1)--> 1 --add(3)--> 4 --mul(3)--> 12
0 --add(2)--> 2 --add(2)--> 4 --mul(3)--> 12
0 --add(2)--> 2 --mul(2)--> 4 --mul(3)--> 12
0 --add(3)--> 3 --add(1)--> 4 --mul(3)--> 12
0 --add(2)--> 2 --mul(3)--> 6 --mul(2)--> 12
0 --add(3)--> 3 --mul(2)--> 6 --mul(2)--> 12
0 --add(3)--> 3 --add(3)--> 6 --mul(2)--> 12
0 --add(3)--> 3 --mul(3)--> 9 --add(3)--> 12
深度3的完整图形(仅最短路径!)如下所示 假设:

  • 任何数字都可以多次使用
  • 操作立即完成(无运算符优先级)
在图形上执行广度优先搜索

from collections import defaultdict

def add(lhs, rhs):
    return lhs+rhs

def sub(lhs, rhs):
    return lhs-rhs

def mul(lhs, rhs):
    return lhs*rhs

ops = [add, sub, mul]   #allowed operations

graph = { 0:["0"]}      #graph key is node(number); value is a list of shortest paths to this node 
numbers=[1,2,3]         #allowed numbers in operations
target=12               #target node(number) 
gv_edges=[]             #edges for optional graphviz output 

#breadth first search until target is met
while not target in graph:
    new_graph=defaultdict(list, graph)
    for key in graph:
        #inefficiently searches old nodes also
        for n in numbers:
            for op in ops:
                newkey = op(key, n)
                if newkey not in graph:
                    #not met in previous iterations, keep new edge
                    newvals = ["{} --{}({})--> {}".format(val, op.__name__, n, newkey) for val in new_graph[key]]
                    new_graph[newkey].extend(newvals)    
                    gv_edges.append('"{}" -> "{}" [label="{}({})"]'.format(key, newkey, op.__name__, n))
                else:
                    #already met in previous iterations (shorter paths), do not keep new
                    pass
    graph=dict(new_graph)


#print all solutions
print "Solutions:"
print
for val in graph[target]:
    print val
print
print

#print optional graphviz digraph
gv_digraph='digraph {{ rankdir=LR ranksep=2\n"{}" [color=green style=filled fillcolor=green]\n{}\n}}'.format(target,"\n".join(gv_edges))
print "Graphviz Digraph for paste into http://stamm-wilbrandt.de/GraphvizFiddle/"
print "do this for reasonable number of edges only"
print
print gv_digraph
产生以下解决方案:

0 --add(1)--> 1 --add(3)--> 4 --mul(3)--> 12
0 --add(2)--> 2 --add(2)--> 4 --mul(3)--> 12
0 --add(2)--> 2 --mul(2)--> 4 --mul(3)--> 12
0 --add(3)--> 3 --add(1)--> 4 --mul(3)--> 12
0 --add(2)--> 2 --mul(3)--> 6 --mul(2)--> 12
0 --add(3)--> 3 --mul(2)--> 6 --mul(2)--> 12
0 --add(3)--> 3 --add(3)--> 6 --mul(2)--> 12
0 --add(3)--> 3 --mul(3)--> 9 --add(3)--> 12
深度3的完整图形(仅最短路径!)如下所示

这是一个程序性问题还是一个简单的逻辑问题想象一个图形:起始节点是零,它通过表示一个操作(加法、乘法、减法)的边与其他节点相连,第二个操作导致一个节点表示的结果。我将把这种方法的困难留给你,希望我没有破坏你。顺便说一句:你可以使用xdot来显示图表。看起来有人在要求解决他/她的家庭作业:-(每个人都忽略了这样一个事实:a)你可以多次操作,或者b)算法必须终止。连续搜索(宽度优先或其他)的图形对于
9 18 27 36 45
等数字是不可判定的。根据我写的一个程序,我可以告诉你,如果一组五个数字的总和不能达到42,那么所有的数字都是一个特定数字的倍数。重读这个问题后,我意识到我做出了以下假设:数字可以多次使用(不仅仅是运算),五个数字是唯一的,这五个数字介于1和52之间
paxdiablo
做出了一个合理的假设,尽管它使问题变得相当简单:(.这是一个编程问题还是一个简单的逻辑问题想象一个图形:起始节点是零,它通过表示操作(加法、乘法、减法)的边连接到其他节点)和第二个操作,导致一个节点表示的结果。我将省去该方法的困难,希望我没有破坏它。顺便说一句:你可以使用例如xdot来显示图形。看起来有人在要求解决他/她的家庭作业:-(每个人都忽略了a)您可以多次执行操作,或者b)算法必须终止。连续搜索(宽度优先或其他)的图形对于
9 18 27 36 45
等数字是不可判定的。根据我写的一个程序,我可以告诉你,如果一组五个数字的总和不能达到42,那么所有的数字都是一个特定数字的倍数。重读这个问题后,我意识到我做出了以下假设:数字可以多次使用(不仅仅是运算),五个数字是唯一的,这五个数字介于1和52之间
paxdiablo
做出了一个合理的假设,尽管它使问题变得相当琐碎:(.这是一个编程问题还是一个简单的逻辑问题想象一个图形:起始节点是零,它通过表示一个操作(加法、乘法、减法)的边和第二个操作符leadi连接到其他节点