Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
147
Task/Yellowstone-sequence/Python/yellowstone-sequence.py
Normal file
147
Task/Yellowstone-sequence/Python/yellowstone-sequence.py
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
'''Yellowstone permutation OEIS A098550'''
|
||||
|
||||
from itertools import chain, count, islice
|
||||
from operator import itemgetter
|
||||
from math import gcd
|
||||
|
||||
from matplotlib import pyplot
|
||||
|
||||
|
||||
# yellowstone :: [Int]
|
||||
def yellowstone():
|
||||
'''A non-finite stream of terms from
|
||||
the Yellowstone permutation.
|
||||
OEIS A098550.
|
||||
'''
|
||||
# relativelyPrime :: Int -> Int -> Bool
|
||||
def relativelyPrime(a):
|
||||
return lambda b: 1 == gcd(a, b)
|
||||
|
||||
# nextWindow :: (Int, Int, [Int]) -> (Int, Int, [Int])
|
||||
def nextWindow(triple):
|
||||
p2, p1, rest = triple
|
||||
[rp2, rp1] = map(relativelyPrime, [p2, p1])
|
||||
|
||||
# match :: [Int] -> (Int, [Int])
|
||||
def match(xxs):
|
||||
x, xs = uncons(xxs)['Just']
|
||||
return (x, xs) if rp1(x) and not rp2(x) else (
|
||||
second(cons(x))(
|
||||
match(xs)
|
||||
)
|
||||
)
|
||||
n, residue = match(rest)
|
||||
return (p1, n, residue)
|
||||
|
||||
return chain(
|
||||
range(1, 3),
|
||||
map(
|
||||
itemgetter(1),
|
||||
iterate(nextWindow)(
|
||||
(2, 3, count(4))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
# TEST ----------------------------------------------------
|
||||
# main :: IO ()
|
||||
def main():
|
||||
'''Terms of the Yellowstone permutation.'''
|
||||
|
||||
print(showList(
|
||||
take(30)(yellowstone())
|
||||
))
|
||||
pyplot.plot(
|
||||
take(100)(yellowstone())
|
||||
)
|
||||
pyplot.xlabel(main.__doc__)
|
||||
pyplot.show()
|
||||
|
||||
|
||||
# GENERIC -------------------------------------------------
|
||||
|
||||
# Just :: a -> Maybe a
|
||||
def Just(x):
|
||||
'''Constructor for an inhabited Maybe (option type) value.
|
||||
Wrapper containing the result of a computation.
|
||||
'''
|
||||
return {'type': 'Maybe', 'Nothing': False, 'Just': x}
|
||||
|
||||
|
||||
# Nothing :: Maybe a
|
||||
def Nothing():
|
||||
'''Constructor for an empty Maybe (option type) value.
|
||||
Empty wrapper returned where a computation is not possible.
|
||||
'''
|
||||
return {'type': 'Maybe', 'Nothing': True}
|
||||
|
||||
|
||||
# cons :: a -> [a] -> [a]
|
||||
def cons(x):
|
||||
'''Construction of a list from x as head,
|
||||
and xs as tail.
|
||||
'''
|
||||
return lambda xs: [x] + xs if (
|
||||
isinstance(xs, list)
|
||||
) else x + xs if (
|
||||
isinstance(xs, str)
|
||||
) else chain([x], xs)
|
||||
|
||||
|
||||
# iterate :: (a -> a) -> a -> Gen [a]
|
||||
def iterate(f):
|
||||
'''An infinite list of repeated
|
||||
applications of f to x.
|
||||
'''
|
||||
def go(x):
|
||||
v = x
|
||||
while True:
|
||||
yield v
|
||||
v = f(v)
|
||||
return go
|
||||
|
||||
|
||||
# second :: (a -> b) -> ((c, a) -> (c, b))
|
||||
def second(f):
|
||||
'''A simple function lifted to a function over a tuple,
|
||||
with f applied only to the second of two values.
|
||||
'''
|
||||
return lambda xy: (xy[0], f(xy[1]))
|
||||
|
||||
|
||||
# showList :: [a] -> String
|
||||
def showList(xs):
|
||||
'''Stringification of a list.'''
|
||||
return '[' + ','.join(repr(x) for x in xs) + ']'
|
||||
|
||||
|
||||
# take :: Int -> [a] -> [a]
|
||||
# take :: Int -> String -> String
|
||||
def take(n):
|
||||
'''The prefix of xs of length n,
|
||||
or xs itself if n > length xs.
|
||||
'''
|
||||
return lambda xs: (
|
||||
xs[0:n]
|
||||
if isinstance(xs, (list, tuple))
|
||||
else list(islice(xs, n))
|
||||
)
|
||||
|
||||
|
||||
# uncons :: [a] -> Maybe (a, [a])
|
||||
def uncons(xs):
|
||||
'''The deconstruction of a non-empty list
|
||||
(or generator stream) into two parts:
|
||||
a head value, and the remaining values.
|
||||
'''
|
||||
if isinstance(xs, list):
|
||||
return Just((xs[0], xs[1:])) if xs else Nothing()
|
||||
else:
|
||||
nxt = take(1)(xs)
|
||||
return Just((nxt[0], xs)) if nxt else Nothing()
|
||||
|
||||
|
||||
# MAIN ---
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue