Another update from ingydotnet^djgoku

This commit is contained in:
Ingy döt Net 2015-11-18 06:14:39 +00:00
parent 91df62d461
commit 948b86eafa
7604 changed files with 108452 additions and 22726 deletions

View file

@ -0,0 +1,44 @@
-- polynomial utils
a `nmul` n = map (*n) a
a `ndiv` n = map (`div` n) a
instance (Integral a) => Num [a] where
(+) = zipWith (+)
negate = map negate
a * b = foldr f undefined b where
f x z = (a `nmul` x) + (0 : z)
abs _ = undefined
signum _ = undefined
fromInteger n = fromInteger n : repeat 0
-- replace x in polynomial with x^n
repl a n = concatMap (: replicate (n-1) 0) a
-- S2: (a^2 + b)/2
cycleIndexS2 a b = (a*a + b)`ndiv` 2
-- S4: (a^4 + 6 a^2 b + 8 a c + 3 b^2 + 6 d) / 24
cycleIndexS4 a b c d = ((a ^ 4) +
(a ^ 2 * b) `nmul` 6 +
(a * c) `nmul` 8 +
(b ^ 2) `nmul` 3 +
d `nmul` 6) `ndiv` 24
a598 = x1
-- A000598: A(x) = 1 + (1/6)*x*(A(x)^3 + 3*A(x)*A(x^2) + 2*A(x^3))
x1 = 1 : ((x1^3) + ((x2*x1)`nmul` 3) + (x3`nmul`2)) `ndiv` 6
x2 = x1`repl`2
x3 = x1`repl`3
x4 = x1`repl`4
-- A000678 = x CycleIndex(S4, A000598(x))
a678 = 0 : cycleIndexS4 x1 x2 x3 x4
-- A000599 = CycleIndex(S2, A000598(x) - 1)
a599 = cycleIndexS2 (0 : tail x1) (0 : tail x2)
-- A000602 = A000678(x) - A000599(x) + A000599(x^2)
a602 = a678 - a599 + x2
main = mapM_ print $ take 200 $ zip [0 ..] a602

View file

@ -0,0 +1,113 @@
from itertools import count, chain, tee, islice, cycle
from fractions import Fraction
from sys import setrecursionlimit
setrecursionlimit(5000)
def frac(a,b): return a//b if a%b == 0 else Fraction(a,b)
# infinite polynomial class
class Poly:
def __init__(self, gen = None):
self.gen, self.source = (None, gen) if type(gen) is Poly \
else (gen, None)
def __iter__(self):
# We're essentially tee'ing it everytime the iterator
# is, well, iterated. This may be excessive.
return Poly(self)
def getsource(self):
if self.gen == None:
s = self.source
s.getsource()
s.gen, self.gen = tee(s.gen, 2)
def next(self):
self.getsource()
return next(self.gen)
__next__ = next
# Overload "<<" as stream input operator. Hey, C++ does it.
def __lshift__(self, a): self.gen = a
# The other operators are pretty much what one would expect
def __neg__(self): return Poly(-x for x in self)
def __sub__(a, b): return a + (-b)
def __rsub__(a, n):
a = Poly(a)
def gen():
yield(n - next(a))
for x in a: yield(-x)
return Poly(gen())
def __add__(a, b):
if type(b) is Poly:
return Poly(x + y for (x,y) in zip(a,b))
a = Poly(a)
def gen():
yield(next(a) + b)
for x in a: yield(x)
return Poly(gen())
def __radd__(a,b):
return a + b
def __mul__(a,b):
if not type(b) is Poly:
return Poly(x*b for x in a)
def gen():
s = Poly(cycle([0]))
for y in b:
s += y*a
yield(next(s))
return Poly(gen())
def __rmul__(a,b): return a*b
def __truediv__(a,b):
if not type(b) is Poly:
return Poly(frac(x, b) for x in a)
a, b = Poly(a), Poly(b)
def gen():
r, bb = a,next(b)
while True:
aa = next(r)
q = frac(aa, bb)
yield(q)
r -= q*b
return Poly(gen())
def repl(self, n):
def gen():
for x in self:
yield(x)
for i in range(n-1): yield(0)
return Poly(gen())
def __pow__(self, n):
return Poly(self) if n == 1 else self * self**(n-1)
def S2(a,b): return (a*a + b)/2
def S4(a,b,c,d): return a**4/24 + a**2*b/4 + a*c/3 + b**2/8 + d/4
x1 = Poly()
x2 = x1.repl(2)
x3 = x1.repl(3)
x4 = x1.repl(4)
x1 << chain([1], (x1**3 + 3*x1*x2 + 2*x3)/6)
a598 = x1
a678 = Poly(chain([0], S4(x1, x2, x3, x4)))
a599 = S2(x1 - 1, x2 - 1)
a602 = a678 - a599 + x2
for n,x in zip(count(0), islice(a602, 500)): print(n,x)