|
@@ -16,40 +16,50 @@ def parse(line):
|
|
|
operand = parts[2]
|
|
operand = parts[2]
|
|
|
return parts[0], parts[1], operand
|
|
return parts[0], parts[1], operand
|
|
|
|
|
|
|
|
-def simplify(e, conditions):
|
|
|
|
|
|
|
+def simplify(e, constraints):
|
|
|
lconst = isinstance(e.left, int)
|
|
lconst = isinstance(e.left, int)
|
|
|
rconst = isinstance(e.right, int)
|
|
rconst = isinstance(e.right, int)
|
|
|
|
|
|
|
|
if lconst and rconst:
|
|
if lconst and rconst:
|
|
|
return int(OPS[e.opcode](e.left, e.right))
|
|
return int(OPS[e.opcode](e.left, e.right))
|
|
|
elif lconst and e.opcode in ('add', 'mul', 'eql'):
|
|
elif lconst and e.opcode in ('add', 'mul', 'eql'):
|
|
|
- return simplify(Expr(e.opcode, e.right, e.left), conditions)
|
|
|
|
|
|
|
+ return simplify(Expr(e.opcode, e.right, e.left), constraints)
|
|
|
|
|
|
|
|
if e.opcode == 'add':
|
|
if e.opcode == 'add':
|
|
|
|
|
+ # a + 0 -> a
|
|
|
|
|
+ # (a + 1) + 2 -> a + 3
|
|
|
if e.right == 0:
|
|
if e.right == 0:
|
|
|
return e.left
|
|
return e.left
|
|
|
if e.left.opcode == 'add':
|
|
if e.left.opcode == 'add':
|
|
|
return Expr('add', e.left.left, e.left.right + e.right)
|
|
return Expr('add', e.left.left, e.left.right + e.right)
|
|
|
elif e.opcode == 'mul':
|
|
elif e.opcode == 'mul':
|
|
|
|
|
+ # a * 0 -> 0
|
|
|
|
|
+ # a * 1 -> a
|
|
|
if e.right == 0:
|
|
if e.right == 0:
|
|
|
return 0
|
|
return 0
|
|
|
if e.right == 1:
|
|
if e.right == 1:
|
|
|
return e.left
|
|
return e.left
|
|
|
elif e.opcode == 'eql':
|
|
elif e.opcode == 'eql':
|
|
|
|
|
+ # ((a % 26) + larger_than_9) == inp[i] -> 0
|
|
|
|
|
+ # (inp[i] + offset) == inp[j] -> 1, record constraint (i, j, offset)
|
|
|
offset = e.left.right
|
|
offset = e.left.right
|
|
|
if rconst or offset > 9:
|
|
if rconst or offset > 9:
|
|
|
return 0
|
|
return 0
|
|
|
- conditions.append((e.left.left.left, e.right.left, offset))
|
|
|
|
|
|
|
+ constraints.append((e.left.left.left, e.right.left, offset))
|
|
|
return 1
|
|
return 1
|
|
|
elif e.opcode == 'div':
|
|
elif e.opcode == 'div':
|
|
|
|
|
+ # a / 1 -> a
|
|
|
|
|
+ # ((a * 26) + b) / 26 -> a
|
|
|
return e.left if e.right == 1 else e.left.left.left
|
|
return e.left if e.right == 1 else e.left.left.left
|
|
|
elif e.opcode == 'mod':
|
|
elif e.opcode == 'mod':
|
|
|
|
|
+ # (inp[i] + smaller_than_17) % 26 -> inp[i] + smaller_than_17
|
|
|
|
|
+ # ((a * 26) + b) % 26 -> b
|
|
|
return e.left if e.left.left.opcode == 'inp' else e.left.right
|
|
return e.left if e.left.left.opcode == 'inp' else e.left.right
|
|
|
|
|
|
|
|
return e
|
|
return e
|
|
|
|
|
|
|
|
-def input_conditions(nomad):
|
|
|
|
|
- conditions = []
|
|
|
|
|
|
|
+def input_constraints(nomad):
|
|
|
|
|
+ constraints = []
|
|
|
regs = {'w': 0, 'x': 0, 'y': 0, 'z': 0}
|
|
regs = {'w': 0, 'x': 0, 'y': 0, 'z': 0}
|
|
|
index = 0
|
|
index = 0
|
|
|
for opcode, reg, operand in nomad:
|
|
for opcode, reg, operand in nomad:
|
|
@@ -59,16 +69,16 @@ def input_conditions(nomad):
|
|
|
else:
|
|
else:
|
|
|
if not isinstance(operand, int):
|
|
if not isinstance(operand, int):
|
|
|
operand = regs[operand]
|
|
operand = regs[operand]
|
|
|
- regs[reg] = simplify(Expr(opcode, regs[reg], operand), conditions)
|
|
|
|
|
- return conditions
|
|
|
|
|
|
|
+ regs[reg] = simplify(Expr(opcode, regs[reg], operand), constraints)
|
|
|
|
|
+ return constraints
|
|
|
|
|
|
|
|
-def modelnum(conditions, largest):
|
|
|
|
|
|
|
+def modelnum(constraints, largest):
|
|
|
nr = [0] * 14
|
|
nr = [0] * 14
|
|
|
- for a, b, offset in conditions:
|
|
|
|
|
|
|
+ for a, b, offset in constraints:
|
|
|
nr[a] = 9 - max(offset, 0) if largest else 1 - min(offset, 0)
|
|
nr[a] = 9 - max(offset, 0) if largest else 1 - min(offset, 0)
|
|
|
nr[b] = nr[a] + offset
|
|
nr[b] = nr[a] + offset
|
|
|
return ''.join(map(str, nr))
|
|
return ''.join(map(str, nr))
|
|
|
|
|
|
|
|
-conditions = input_conditions(map(parse, sys.stdin))
|
|
|
|
|
-print(modelnum(conditions, True))
|
|
|
|
|
-print(modelnum(conditions, False))
|
|
|
|
|
|
|
+constraints = input_constraints(map(parse, sys.stdin))
|
|
|
|
|
+print(modelnum(constraints, True))
|
|
|
|
|
+print(modelnum(constraints, False))
|