# 1-((2+3)*4) = -19
ptns = '''
N?N?N?N
N?N?(N?N)
N?(N?N)?N
N?(N?N?N)
N?(N?(N?N))
N?((N?N)?N)
(N?N?N)?N
(N?(N?N))?N
((N?N)?N)?N'''.splitlines()
def permute(x):
def pmt(x, y, n, i):
if i == n: yield y
for j in range(n):
if x[j] == 99: continue
y[i] = s = x[j]; x[j] = 99
yield from pmt(x, y, n, i + 1)
x[j] = s
n = len(x)
return pmt(x, list(range(n)), n, 0)
x = ('1 2 3 4' if 1 else input()).split()
if len(x) != 4: exit()
for n_ in permute(x):
for p_ in permute(['+', '-', '*']):
for t in ptns:
e = ''; n = n_.copy(); p = p_.copy()
for u in t:
if u == '?': e += p.pop()
elif u == 'N': e += n.pop()
else: e += u
print(e, '=', eval(e))
N?N?(N?N)可是自動生成滴:
import ply.lex as lex # pip install ply
import ply.yacc as yacc
from functools import reduce
tokens = ('WORD',); t_WORD = r'[\w+\+\-\*\/\(\)\?]'; literals = (':', ';')
t_ignore = ' \t\r\n'
def t_error(t): raise SyntaxError()
d = {}
def p_1(p): "rules : rule"
def p_2(p): "rules : rule rules"
def p_4(p):
"rule : WORD ':' words ';'"
k = p[1]; v = d.get(k, []); v.append([p[3]])
d[k] = v
def p_5(p): "words : WORD"; p[0] = [p[1]]
def p_6(p): "words : WORD words"; p[0] = [p[1]] + p[2]
lexer = lex.lex()
istr = '''
e : N ;
e : N ? e ;
e : N ? (e) ;
e : (e) ? N ;
'''
try:
yacc.yacc().parse(istr)
except SyntaxError: quit()
seen = set()
def gen(s):
if len(s) > 11: return
expanded = False
for i in range(len(s)):
w = s[i]
for r in d.get(w, []):
expanded = True
gen(s[:i] + r[0] + s[i + 1:])
e = reduce(lambda a,b:a+b, s)
if e in seen: return
seen.add(e)
if not expanded:
if e.count('?') == 3: print(e)
gen(['e'])
我吹了一點牛。(N)我幹不掉,于是串替換成N,再一看有重複的,手工删掉了。()是個重要的發明,沒有它,計算機代數系統代數時會麻煩不少吧。