Last active
October 1, 2020 19:36
-
-
Save iliakonnov/f3543495ab17231bb90cc1c82c060699 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
!<arch> | |
7.1b.log/ 0 0 0 644 176 ` | |
1 7 7 9 | |
7 5 1 -1 | |
4 2 -1 -3 | |
-1 1 3 5 | |
~2 - 7*~1 | |
~3 - 4*~1 | |
~4 + ~1 | |
~2 / 4 | |
~4 / 2 | |
~3 - 2*~2 + ~4 | |
~1 + ~2 + ~4 | |
~2 + (11 / 4)*~4 | |
2 @ 3 | |
4 @ 2 | |
~2 / 4 | |
~3 / (7/4) | |
~2 - (5/4)*~3 | |
7.1b_.log/ 0 0 0 644 256 ` | |
1 0 0 0 | |
0 1 0 0 | |
0 0 1 0 | |
0 0 0 1 | |
~2 - 7*~1 | |
~3 - 4*~1 | |
~4 + ~1 | |
#1 | |
~2 / 4 | |
~4 / 2 | |
#1 | |
~3 - 2*~2 + ~4 | |
#1 | |
~1 + ~2 + ~4 | |
#1 | |
~2 + (11 / 4)*~4 | |
#1 | |
2 @ 3 | |
4 @ 2 | |
#1 | |
~2 - 7*~1 | |
~3 - 4*~1 | |
~4 + ~1 | |
~2 / 4 | |
~4 / 2 | |
~3 - 2*~2 + ~4 | |
~1 + ~2 + ~4 | |
~2 + (11 / 4)*~4 | |
2 @ 3 | |
4 @ 2 | |
7.1d.log/ 0 0 0 644 236 ` | |
-6 4 8 -1 6 | |
-5 2 4 1 3 | |
7 2 4 1 3 | |
2 4 8 -7 6 | |
3 2 4 -5 3 | |
~1 + 2*~5 | |
~2 + ~4 + ~5 | |
~1 - ~2 | |
~2 - ~3 - ~4 - ~5 | |
~2 / -12 | |
5*~4 - ~3 - ~5 | |
~3 * 3 - 7*~5 | |
~5 - 3*~2 | |
2*~3 + ~4 | |
8*~5 - ~4 | |
~3 / 45 | |
~4 / 16 | |
~5 / -9 | |
~5 - ~3 | |
~4 + 31/16*~3 | |
2@1 | |
4@2 | |
7.1v.log/ 0 0 0 644 167 ` | |
4 1 7 -5 1 | |
0 -7 1 -3 -5 | |
3 4 5 -3 2 | |
2 5 3 -1 3 | |
~1 + ~4 - 2*~3 | |
3*~4 - 2*~3 | |
~2 + ~4 | |
2*~4 + 7*~1 | |
3 @ 1 | |
3 @ 2 | |
4 @ 3 | |
~1 + 2*~2 | |
~1 + 5/2 * ~3 | |
~1 / 3 | |
~2 / -2 | |
~3 / -2 | |
8.1a.log/ 0 0 0 644 106 ` | |
5 3 5 12 10 | |
2 2 3 5 4 | |
1 7 9 4 2 | |
~1 - 5*~3 | |
~2 - 2*~3 | |
~1 / -8 | |
~2 / -3 | |
~1 - ~2 | |
~2 / 4 | |
~3 - 7*~2 | |
1 @ 3 | |
8.1g.log/ 0 0 0 644 80 ` | |
12 9 3 10 13 | |
4 3 1 2 3 | |
8 6 2 5 7 | |
~1 - ~2 - ~3 | |
~3 - 2*~2 | |
~1 - 3*~3 | |
~2 - 2*~3 | |
8.1v.log/ 0 0 0 644 117 ` | |
-9 10 3 7 7 | |
-4 7 1 3 5 | |
7 5 -4 -6 3 | |
~1 - 3*~2 | |
~3 + 4*~2 | |
~3 + 3*~1 | |
~1 - 8*~3 | |
~2 + 5*~3 | |
~1 / -2 | |
~3 / -1 | |
~2 - 3*~1 | |
8.6d.log/ 0 0 0 644 85 ` | |
1 1 1 6 | |
-1 1 1 0 | |
1 -1 1 2 | |
~2 + ~1 | |
~3 - ~1 | |
~2 / 2 | |
~3 / 2 | |
~3 + ~2 | |
~1 - ~2 | |
~2 - ~3 | |
8.6g.log/ 0 0 0 644 86 ` | |
2 1 1 3 | |
1 2 1 0 | |
1 1 2 0 | |
~1 - 2*~3 | |
~2 - ~3 | |
~1 + ~2 | |
~3 - ~2 | |
~2 - ~1/4 | |
~3 + ~1 * 3/4 | |
8.8.log/ 0 0 0 644 192 ` | |
-8 4 -2 1 1 | |
-1 1 -1 1 3 | |
1 1 1 1 13 | |
8 4 2 1 33 | |
~1 + 8*~3 | |
~2 + ~3 | |
~4 - 8*~3 | |
~1 / 3 | |
~2 / 2 | |
~1 - 4*~2 | |
~3 - ~2 | |
~4 + 4*~2 | |
~1 / 2 | |
~4 / 3 | |
~3 - ~1 | |
~4 + 2*~1 | |
~4 / -2 | |
~1 + ~4/2 | |
~2 - ~4 | |
~3 - ~4/2 | |
822.log/ 0 0 0 644 86 ` | |
0 -3 2 0 0 | |
-2 -3 0 2 0 | |
3 0 3 -3 0 | |
0 3 -2 0 0 | |
~3 / 3 | |
~2 + 2*~3 + ~4 | |
~1 + ~4 | |
~4 / 3 | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import readline | |
import sympy | |
from simpleeval import SimpleEval | |
import tabulate | |
import ast | |
from sys import argv | |
def S(*args, **kwargs): | |
return sympy.S(*args, **kwargs) | |
num_map = [(1000, 'M'), (900, 'CM'), (500, 'D'), (400, 'CD'), (100, 'C'), (90, 'XC'), | |
(50, 'L'), (40, 'XL'), (10, 'X'), (9, 'IX'), (5, 'V'), (4, 'IV'), (1, 'I')] | |
def num2roman(num): | |
roman = '' | |
while num > 0: | |
for i, r in num_map: | |
while num >= i: | |
roman += r | |
num -= i | |
return roman | |
class Swap: | |
def __init__(self, a, b): | |
self.a = int(a) | |
self.b = int(b) | |
def __str__(self): | |
return f'{num2roman(self.a)} <-> {num2roman(self.b)}' | |
def display(self): | |
return str(self) | |
def apply(self, m): | |
res = [row[:] for row in m] | |
(res[self.a - 1], res[self.b - 1]) = (res[self.b - 1], res[self.a - 1]) | |
return res | |
class RowRef: | |
def __init__(self, idx, mul=None, add=None): | |
self.idx = idx | |
self._mul = S(1) if mul is None else mul | |
self._add = [] if add is None else add | |
self._swap = None | |
def mul(self, x): | |
return RowRef(self.idx, self._mul * x, self._add) | |
def add(self, x): | |
return RowRef(self.idx, self._mul, self._add + [x]) | |
def __str__(self): | |
s = '' | |
for i in self._add: | |
s += f' + {i}' | |
if self._mul == 1: | |
m = '' | |
elif self._mul == -1: | |
m = '-' | |
else: | |
m = str(self._mul) | |
if ' ' in m: | |
m = f'({m})' | |
else: | |
m = f'{m} * ' | |
return f'{m}[{num2roman(self.idx)}]{s}' | |
def display(self): | |
return f'[{num2roman(self.idx)}] := {self}' | |
def resolve(self, m): | |
row = m[self.idx - 1] | |
row = [i*self._mul for i in row] | |
for other in self._add: | |
other_row = other.resolve(m) | |
for i in range(len(row)): | |
row[i] += other_row[i] | |
return row | |
def apply(self, m): | |
res = [row[:] for row in m] | |
res[self.idx - 1] = self.resolve(m) | |
return res | |
def _div(a, b): | |
if isinstance(a, RowRef): | |
return a.mul(S(1) / S(b)) | |
elif isinstance(b, RowRef): | |
raise Exception('Division by RowRef') | |
else: | |
return S(a) / S(b) | |
def _mul(a, b): | |
if isinstance(a, RowRef): | |
return a.mul(S(b)) | |
elif isinstance(b, RowRef): | |
return b.mul(S(a)) | |
else: | |
return S(a) * S(b) | |
def _add(a, b): | |
if isinstance(a, RowRef) and isinstance(b, RowRef): | |
return a.add(b) | |
else: | |
return S(a) + S(b) | |
def _sub(a, b): | |
if isinstance(a, RowRef) and isinstance(b, RowRef): | |
return a.add(b.mul(-1)) | |
else: | |
return S(a) - S(b) | |
s = SimpleEval() | |
s.operators = {**s.operators, **{ | |
ast.Div: _div, | |
ast.Mult: _mul, | |
ast.Add: _add, | |
ast.Sub: _sub, | |
ast.Invert: RowRef, | |
ast.MatMult: Swap | |
}} | |
s.names = lambda node: S(node.id) | |
def strip(s, start): | |
while s.startswith(start): | |
s = s[len(start):] | |
return s | |
def read_matrix(): | |
res = [] | |
while ln := strip(input('M: '), 'M: '): | |
res.append([S(i) for i in ln.split() if i]) | |
if len(res) >= 2: | |
assert len(res[-1]) == len(res[-2]) | |
return res | |
def colorize(el): | |
if el == -1: | |
return f'\x1b[31m{el}\x1b[0m' | |
if el == 1: | |
return f'\x1b[32m{el}\x1b[0m' | |
if el == 0: | |
return f'\x1b[34m{el}\x1b[0m' | |
return sympy.pretty(el, use_unicode=True) | |
tabulate.PRESERVE_WHITESPACE = True | |
def print_matrix(ms, idx=None, depth=None, indent=0): | |
new_ms = [] | |
for row in range(len(ms[0])): | |
# new_row = [f'~{row+1}'] | |
new_row = [] | |
for i in range(len(ms)): | |
if new_row: | |
new_row.append(' ') | |
new_row += ms[i][row] | |
new_ms.append(new_row) | |
tab = tabulate.tabulate( | |
[[colorize(el) for el in row] for row in new_ms], | |
tablefmt='fancy_grid' | |
) | |
if idx is not None: | |
idx_s = f'[#{idx}]: '.ljust(indent) | |
else: | |
idx_s = ' ' * indent | |
if depth is not None: | |
dep_s = f'({depth})'.ljust(indent).ljust(len(str(idx_s))) | |
else: | |
dep_s = ' ' * indent | |
lines = tab.split('\n') | |
left = max(len(str(idx_s)), len(str(dep_s))) | |
placeholder = ' ' * left | |
for i, ln in enumerate(lines): | |
if i == 1: | |
print(idx_s + ln) | |
elif i == 2: | |
print(dep_s + ln) | |
else: | |
print(placeholder + ln) | |
return left | |
def dump_matrix(m): | |
flat = [[str(i) for i in row] for row in m] | |
print(tabulate.tabulate(flat, tablefmt='presto')) | |
class State: | |
def __init__(self): | |
self.history = None | |
self.depths = None | |
self.matrix = [] | |
self.depth = 0 | |
self.display = False | |
def maybe_display(self): | |
if self.display: | |
self.force_display() | |
def force_display(self): | |
self.history.append(self.matrix) | |
self.depths.append(self.depth) | |
self.depth += 1 | |
indent = print_matrix([self.matrix], len(self.history), self.depth) | |
simplified = [[sympy.simplify(i) for i in row] for row in self.matrix] | |
self.display = str(simplified) != str(self.matrix) | |
self.matrix = simplified | |
self.maybe_display() | |
def question(self): | |
return 'M: ' if self.history is None else '> ' | |
def _read_matrix(self, ln): | |
ln = strip(ln, 'M: ') | |
if ln: | |
self.matrix.append([S(i) for i in ln.split() if i]) | |
if len(self.matrix) >= 2: | |
assert len(self.matrix[-1]) == len(self.matrix[-2]) | |
else: | |
self.history = [] | |
self.depths = [] | |
self.display = True | |
def enter(self, ln, edit=True): | |
if self.history is None: | |
return self._read_matrix(ln) | |
prefix = f'\x1b[F{self.question()}{ln} \t $' if edit else '$' | |
ln = strip(ln, '> ').split('$')[0].strip() | |
if not ln: | |
self.display = True | |
elif ln == 'D': | |
dump_matrix(self.matrix) | |
elif ln == '#': | |
print(f'{prefix} RESET') | |
self.matrix = self.history[-1] | |
elif ln.startswith('#'): | |
goto = int(ln[1:]) | |
print(f'{prefix} GOTO {goto}') | |
self.matrix = self.history[goto - 1] | |
self.depth = self.depths[goto - 1] | |
else: | |
expr = s.eval(ln) | |
print(f'{prefix} {expr.display()}') | |
self.matrix = expr.apply(self.matrix) | |
def main(): | |
state = State() | |
log = 'matrix.log' if len(argv) <= 1 else argv[1] | |
with open(log, 'a+') as f: | |
f.seek(0) | |
for ln in f.readlines(): | |
state.maybe_display() | |
ln = ln.strip() | |
#print(f'LOG|{state.question()}{ln}') | |
state.enter(ln, edit=False) | |
f.seek(0, 2) | |
while True: | |
state.maybe_display() | |
ln = input(state.question()) | |
state.enter(ln) | |
f.write(ln + '\n') | |
f.flush() | |
if __name__ == "__main__": | |
main() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment