在Python中检查唯一输出

Sho*_*len 3 python puzzle

我昨天遇到了一个有趣的数学问题,并解决了,但是我写的代码,我不得不做一个键盘中断,否则它会永远运行,哈哈.因此我将其更改为具有结束条件,但现在它只打印1个解决方案并停止.

问题是这样的:"你有数字123456789,按顺序.在每个数字之间,你必须插入任何内容,加号或乘法符号,以便结果表达式等于2002.编写一个打印所有的程序解决方案.(有两个.)"

import random


def try1(param):
    global solved
    opers = ['+', '*', '']
    hotpotato = ('%s'.join(param) % (random.choice(opers),
                                     random.choice(opers),
                                     random.choice(opers),
                                     random.choice(opers),
                                     random.choice(opers),
                                     random.choice(opers),
                                     random.choice(opers),
                                     random.choice(opers),
                                     )
             )
    if eval(hotpotato) == 2002:
        solved += 1
        print "Solution:", hotpotato, "= 2002     :-)"

    else:
        pass


solved = 0
while solved == 0:
    try1('123456789')
Run Code Online (Sandbox Code Playgroud)

此代码打印它遇到的第一个解决方案并停止.任何人都可以告诉我如何让它在停止前打印两种解决方案吗?

Kar*_*ath 8

不要使用随机,枚举所有可能的运算符组合(好吧,你可以稍微削减搜索空间,如果前两个数字的结果大于2002,则结果不会变小).itertools是你的朋友.

如果你这样做,你的程序将立即完成.

如果您知道有确切两种解决方案,您可以返回从溶液中try1和,直到你收集到两种不同的解决方案做的环,但不是真正的优雅,是吗?


utd*_*mir 5

问题的解决方案是,在解决时破坏== 2.

但是你的代码真正的问题是随机使用.在算法中使用随机通常是个坏主意.您的代码有可能持续一个多世纪.

使用itertools有更简单快捷的方法:

import itertools

for s in itertools.product(("+", "*", ""), repeat=8):
    z = itertools.izip_longest("123456789", s, fillvalue="")
    e = "".join(itertools.chain.from_iterable(z))

    if eval(e) == 2002:
        print(e)
Run Code Online (Sandbox Code Playgroud)

找到两个解决方案时无需中断,因为代码已在0.2秒内完成:).