当我和一群书呆子在一起时,我喜欢玩一个有趣的纸牌游戏。
规则很简单:一个人放下四张牌。在这个版本的游戏中,皇室成员数为10.游戏的目的是通过使用任何二元运算符来制作24。举个例子:
10,2,3,6
(10-6)*(2 * 3)
4 * 6
24
那么......为什么不用计算机用蛮力来解决这个问题?
from math import floor,ceil
for i in range(1000): # not 10,000 yet. It would run too long.
one, two, three, four = i//(1000)+1,(i%1000)//100+1,(i%100)//10+1,i%10+1
operand = [int.__add__,
int.__sub__,
int.__mul__,
int.__truediv__,
int.__pow__,
int.__mod__,
int.__or__, # even though I'd have to be a pedant to use these, I'm still curious
int.__and__,
int.__xor__,
int.__lshift__,
int.__rshift__]
op_str = {int.__add__:"+",
int.__sub__:"-",
int.__mul__:"*",
int.__truediv__:"/",
int.__pow__:"**",
int.__mod__:"%",
int.__or__:"|",
int.__and__:"&",
int.__xor__:"^",
int.__lshift__:"<<",
int.__rshift__:">>"}
for j in range(pow(len(operand),3)):
try:
a = operand[j%len(operand)]
b = operand[(j%(len(operand)**2))//len(operand)]
c = operand[(j%(len(operand)**3))//(len(operand)**2)]
# serial
answer = a(one,b(two,c(three,four)))
if ceil(answer) == floor(answer) and answer == 24:
print(one, op_str[a], "(", two, op_str[b], "(", three, op_str[c], four, "))")
print(one, op_str[a], "(", two, op_str[b], "(", c(three, four), "))")
print(one, op_str[a], "(", b(two,c(three,four)), ")")
print(a(one,b(two,c(three,four))))
continue
# tree
answer = c(a(one, two), b(three, four))
if ceil(answer) == floor(answer) and answer == 24:
print("((", one, op_str[a], two, ")", op_str[b], "(", three, op_str[c], four, "))")
print("(", a(one, two), op_str[b], c(three, four), ")")
print(c(a(one, two), b(three, four)))
continue
except Exception:
pass # I just want to bypass any stupid problems with modulus, divide and the shifts
除此之外,我得到了愚蠢的答案:
...
(( 1 % 1 ) * ( 6 | 4 ))
( 0 * 6 )
24
(( 1 - 1 ) * ( 6 + 4 ))
( 0 * 10 )
24
...
有人看到这个问题吗?
答案 0 :(得分:2)
这只是打印输出中的一些拼写错误。您将“树”计算定义为:
answer = c(a(one, two), b(three, four))
以c
为最外层函数。但是,然后用b
作为最外面的函数打印它。这些行:
print("((", one, op_str[a], two, ")", op_str[b], "(", three, op_str[c], four, "))")
print("(", a(one, two), op_str[b], c(three, four), ")")
应为:
print("((", one, op_str[a], two, ")", op_str[c], "(", three, op_str[b], four, "))")
print("(", a(one, two), op_str[c], b(three, four), ")")
您的回答如下:
...
(( 1 % 1 ) | ( 6 * 4 ))
( 0 | 24 )
24
(( 1 - 1 ) + ( 6 * 4 ))
( 0 + 24 )
24
...
答案 1 :(得分:1)
我发现你的代码非常难以理解,所以我想我会尝试更有条理的方法:
import operator as ops
from itertools import permutations, combinations_with_replacement
op = { symbol : getattr(ops, name) for name, symbol in dict(add = '+',
sub = '-',
mul = '*',
truediv = '/').items() }
# etc. I'll let you fill in the rest
class Expression(object):
def __init__(self, opsymbol, left, right):
self.op = op[opsymbol]
self.opsymbol = opsymbol
self.left = left
self.right = right
def __repr__(self):
return "({left} {opsymbol} {right})".format(**vars(self))
def eval(self):
left = evalexp(self.left)
right = evalexp(self.right)
return self.op(left, right)
def show(self):
return '{} = {}'.format(self, self.eval())
def __hash__(self): return hash(repr(self))
def __eq__ (self, other): return repr(self) == repr(other)
def evalexp(e):
return e.eval() if type(e) is Expression else e
def search(*args, target=24):
assert len(args) == 4
found = set()
operators = tuple(combinations_with_replacement(op, 3))
for a,b,c,d in permutations(args):
for op1, op2, op3 in operators:
for o1, o2, o3 in permutations((op1, op2, op3)):
t1 = Expression(o1, a, Expression(o2, b, Expression(o3, c, d)))
t2 = Expression(o1, a, Expression(o2, Expression(o3, b, c), d))
t3 = Expression(o1, Expression(o2, a, b), Expression(o3, c, d))
t4 = Expression(o1, Expression(o2, a, Expression(o3, b, c)), d)
t5 = Expression(o1, Expression(o2, Expression(o3, a, b), c), d)
for e in (t1, t2, t3, t4, t5):
try:
if e.eval() == target:
found.add(e)
except (ZeroDivisionError):
pass
return found
found = search(2,3,6,10, target=24)
for e in found:
print(e.show())
给出56行输出,包括
((10 - 6) * (2 * 3)) = 24
((10 - (2 * 3)) * 6) = 24
(((6 + 10) * 3) / 2) = 24.0
((2 + 10) * (6 / 3)) = 24.0
(((10 + 6) * 3) / 2) = 24.0
((3 / 2) * (6 + 10)) = 24.0
(3 * ((6 + 10) / 2)) = 24.0
((2 * (10 - 6)) * 3) = 24
(6 * ((10 + 2) / 3)) = 24.0
((2 - 10) * (3 - 6)) = 24
(2 * (3 * (10 - 6))) = 24