def process_strategies(n, unfold_front=True): nopscore = lambda x: abs(x) + 3 * (x <= 0) - (x == 0) queue = heapdict([((n, ), (boundscore(n), 0))]) bestscore = 2 * abs(n) + 2 while queue: strat, (score, bound) = queue.popitem() if bound >= bestscore: continue elif score > boundscore(n) + 2: continue resolved = True for i in range(len(strat)): op = strat[i] if isinstance(op, int): score0 = score - boundscore(op) strati = strat[:i] istrat = strat[i + 1:] base = None if resolved: ops = sum(strati, ()) z = _PPVM(ops) if z.stack: base = z.stack[-1] resolved = False for substrat in get_strategies(op, base): score1 = score0 + sum( len(o) if isinstance(o, tuple) else boundscore(o) for o in substrat) bound1 = bound + sum( len(o) if isinstance(o, tuple) else 0 for o in substrat) key = score1, bound1 if bound1 < bestscore and score1 <= boundscore(n) + 2: ssi = strati + substrat + istrat if key < queue.setdefault(ssi, key): queue[ssi] = key if unfold_front: break if resolved and True: bestscore = bound yield n, score, bound, sum(strat, ()) # yield strat if resolved and False: bestscore = bound lq0 = len(queue) queue = heapdict(I for I in queue.items() if I[1][1] < bound) lq1 = len(queue) yield score, bound, queue.peekitem( )[1] if lq1 else None, lq0, lq1, sum(strat, ())
def minimize(n, base=None, bound=None, cache={ (1, None): (1, ), (0, None): (1, 'NOT'), (-1, None): (1, 1, 'NOT', 'SBT') }): if (n, base) in cache: return cache[n, base] if n is None: return cache if bound is None: bound = 3 * abs(n) + 3 nopscore = lambda x: abs(x) + 3 * (x <= 0) - (x == 0) getscore = lambda s: sum( nopscore(x) if isinstance(x, int) else 1 for x in s) if base is None: minops, = bmp(n) else: minops = minimize(n, None, bound // 2) if minops is None: minops, = bmp(n) if bound < abs(n): return minops cache[n, base] = None print "?", minops, n, base bestscore = getscore(minops) strats = list(get_strats(n, base)) for strat in strats: score = 0 ops = () print ">", strat, n, base for m in strat: if isinstance(m, str): ops += m, score += 1 else: if ops: if base is not None and ops[0] == 'DPL': stk = _PPVM((base, ) + ops[1:]).stack else: stk = _PPVM(ops).stack top = stk[-1] if len(stk) == 1 and top != n: mops = minimize(top, None, bound // 2) if mops is not None: mscore = getscore(mops) if score < mscore: if base is None: cache[top, None] = ops else: ops = mops score = mscore else: top = None print "!", n, m, top mm = minimize(m, top, bound // 2) if mm is None: mm, = bmp(m) score += getscore(mm) ops += mm bestscore, minops = min((score, ops), (bestscore, minops)) cache[n, base] = minops return minops
from pietbackend import _const from itertools import chain from optimizer import _PPVM from heapdict import heapdict import math _ppvm = _PPVM() from itertools import chain def process_strategies(n, unfold_front=True): nopscore = lambda x: abs(x) + 3 * (x <= 0) - (x == 0) queue = heapdict([((n, ), (boundscore(n), 0))]) bestscore = 2 * abs(n) + 2 while queue: strat, (score, bound) = queue.popitem() if bound >= bestscore: continue elif score > boundscore(n) + 2: continue resolved = True for i in range(len(strat)): op = strat[i] if isinstance(op, int): score0 = score - boundscore(op) strati = strat[:i] istrat = strat[i + 1:] base = None if resolved: ops = sum(strati, ())
def run(ops): vm = _PPVM() for o in ops: print vm.eval(o), vm.stack, o