Skip to content

Instantly share code, notes, and snippets.

@iliakonnov
Last active October 1, 2020 19:36
Show Gist options
  • Save iliakonnov/f3543495ab17231bb90cc1c82c060699 to your computer and use it in GitHub Desktop.
Save iliakonnov/f3543495ab17231bb90cc1c82c060699 to your computer and use it in GitHub Desktop.
!<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
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