mirror of
https://github.com/osmarks/random-stuff
synced 2024-12-27 10:30:35 +00:00
79 lines
1.8 KiB
Python
79 lines
1.8 KiB
Python
|
from fractions import Fraction
|
|||
|
from functools import reduce
|
|||
|
import sys
|
|||
|
from math import floor
|
|||
|
import random
|
|||
|
|
|||
|
def interpolate(points):
|
|||
|
def mul_polys(p1, p2):
|
|||
|
out = [0] * (len(p1) + len(p2) - 1)
|
|||
|
for i1, c1 in enumerate(p1):
|
|||
|
for i2, c2 in enumerate(p2):
|
|||
|
out[i1 + i2] += c1 * c2
|
|||
|
return out
|
|||
|
def sum_polys(ps):
|
|||
|
out = [0] * max(map(len, ps))
|
|||
|
for p in ps:
|
|||
|
for i, c in enumerate(p):
|
|||
|
out[i] += c
|
|||
|
return out
|
|||
|
def basis(j):
|
|||
|
px = points[j][0]
|
|||
|
out = []
|
|||
|
for x, y in points:
|
|||
|
if x != px:
|
|||
|
div = px - x
|
|||
|
out.append([-Fraction(x, div), Fraction(1, div)])
|
|||
|
return reduce(mul_polys, out)
|
|||
|
out = []
|
|||
|
for i, (x, y) in enumerate(points):
|
|||
|
out.append([c * y for c in basis(i)])
|
|||
|
return sum_polys(out)
|
|||
|
|
|||
|
def evaluate(poly, x):
|
|||
|
y = 0
|
|||
|
for c in reversed(poly):
|
|||
|
y *= x
|
|||
|
y += c
|
|||
|
return y
|
|||
|
|
|||
|
indents = {"\t": 8, " ": 1, " ": Fraction(2, 3), " ": 2, " ": 4, " ": Fraction(4, 3), "": 0}
|
|||
|
def get_indent(line):
|
|||
|
i = 0
|
|||
|
e = 0
|
|||
|
for j, c in enumerate(line):
|
|||
|
if c in indents:
|
|||
|
i += indents[c]
|
|||
|
e = j + 1
|
|||
|
else: break
|
|||
|
return i, e
|
|||
|
|
|||
|
with open(sys.argv[1]) as tplfile:
|
|||
|
counts = [ (lnum, get_indent(line)[0]) for lnum, line in enumerate(tplfile.readlines()) ]
|
|||
|
|
|||
|
counts = random.sample(counts, k=4)
|
|||
|
poly = interpolate(counts)
|
|||
|
|
|||
|
lindents = [ (Fraction(size), char) for char, size in indents.items() if size != 0 ]
|
|||
|
lindents.sort()
|
|||
|
def gen_indent(n):
|
|||
|
n = Fraction(abs(n))
|
|||
|
out = ""
|
|||
|
for (csize, cchar), (nsize, _) in zip(lindents, lindents[1:] + [(100000000000000, " ")]):
|
|||
|
nmult = 0
|
|||
|
while True:
|
|||
|
nxt = nmult + nsize
|
|||
|
if nxt <= n:
|
|||
|
nmult = nxt
|
|||
|
else: break
|
|||
|
|
|||
|
dif = floor((n - nmult) / csize)
|
|||
|
n -= dif * csize
|
|||
|
out += cchar * dif
|
|||
|
return out
|
|||
|
|
|||
|
with open(sys.argv[2]) as infile:
|
|||
|
for lnum, line in enumerate(infile.readlines()):
|
|||
|
line = line[get_indent(line)[1]:]
|
|||
|
print(gen_indent(evaluate(poly, lnum)) + line, end="")
|