Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
|
|
@ -0,0 +1,54 @@
|
|||
from itertools import islice
|
||||
|
||||
class INW():
|
||||
"""
|
||||
Intersecting Number Wheels
|
||||
represented as a dict mapping
|
||||
name to tuple of values.
|
||||
"""
|
||||
|
||||
def __init__(self, **wheels):
|
||||
self._wheels = wheels
|
||||
self.isect = {name: self._wstate(name, wheel)
|
||||
for name, wheel in wheels.items()}
|
||||
|
||||
def _wstate(self, name, wheel):
|
||||
"Wheel state holder"
|
||||
assert all(val in self._wheels for val in wheel if type(val) == str), \
|
||||
f"ERROR: Interconnected wheel not found in {name}: {wheel}"
|
||||
pos = 0
|
||||
ln = len(wheel)
|
||||
while True:
|
||||
nxt, pos = wheel[pos % ln], pos + 1
|
||||
yield next(self.isect[nxt]) if type(nxt) == str else nxt
|
||||
|
||||
def __iter__(self):
|
||||
base_wheel_name = next(self.isect.__iter__())
|
||||
yield from self.isect[base_wheel_name]
|
||||
|
||||
def __repr__(self):
|
||||
return f"{self.__class__.__name__}({self._wheels})"
|
||||
|
||||
def __str__(self):
|
||||
txt = "Intersecting Number Wheel group:"
|
||||
for name, wheel in self._wheels.items():
|
||||
txt += f"\n {name+':':4}" + ' '.join(str(v) for v in wheel)
|
||||
return txt
|
||||
|
||||
def first(iter, n):
|
||||
"Pretty print first few terms"
|
||||
return ' '.join(f"{nxt}" for nxt in islice(iter, n))
|
||||
|
||||
if __name__ == '__main__':
|
||||
for group in[
|
||||
{'A': (1, 2, 3)},
|
||||
{'A': (1, 'B', 2),
|
||||
'B': (3, 4)},
|
||||
{'A': (1, 'D', 'D'),
|
||||
'D': (6, 7, 8)},
|
||||
{'A': (1, 'B', 'C'),
|
||||
'B': (3, 4),
|
||||
'C': (5, 'B')}, # 135143145...
|
||||
]:
|
||||
w = INW(**group)
|
||||
print(f"{w}\n Generates:\n {first(w, 20)} ...\n")
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
def nextfrom(w, name):
|
||||
while True:
|
||||
nxt, w[name] = w[name][0], w[name][1:] + w[name][:1]
|
||||
if '0' <= nxt[0] <= '9':
|
||||
return nxt
|
||||
name = nxt
|
||||
|
||||
if __name__ == '__main__':
|
||||
for group in '''
|
||||
A: 1 2 3
|
||||
A: 1 B 2; B: 3 4
|
||||
A: 1 D D; D: 6 7 8
|
||||
A: 1 B C; B: 3 4; C: 5 B'''.strip().split('\n'):
|
||||
print(f"Intersecting Number Wheel group:\n {group}")
|
||||
wheel, first = {}, None
|
||||
for w in group.strip().split(';'):
|
||||
name, *values = w.strip().split()
|
||||
wheel[name[:-1]] = values
|
||||
first = name[:-1] if first is None else first
|
||||
gen = ' '.join(nextfrom(wheel, first) for i in range(20))
|
||||
print(f" Generates:\n {gen} ...\n")
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
def nextfromr(w, name):
|
||||
nxt, w[name] = w[name][0], w[name][1:] + w[name][:1]
|
||||
return nxt if '0' <= nxt[0] <= '9' else nextfromr(w, nxt)
|
||||
|
||||
if __name__ == '__main__':
|
||||
for group in [{'A': '123'},
|
||||
{'A': '1B2', 'B': '34'},
|
||||
{'A': '1DD', 'D': '678'},
|
||||
{'A': '1BC', 'B': '34', 'C': '5B'},]:
|
||||
print(f"Intersecting Number Wheel group:\n {group}")
|
||||
first = next(group.__iter__())
|
||||
gen = ' '.join(nextfromr(group, first) for i in range(20))
|
||||
print(f" Generates:\n {gen} ...\n")
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
'''Intersecting number wheels'''
|
||||
|
||||
from itertools import cycle, islice
|
||||
from functools import reduce
|
||||
|
||||
|
||||
# clockWorkTick :: Dict -> (Dict, Char)
|
||||
def clockWorkTick(wheelMap):
|
||||
'''The new state of the wheels, tupled with a
|
||||
digit found by recursive descent from a single
|
||||
click of the first wheel.'''
|
||||
def click(wheels):
|
||||
def go(wheelName):
|
||||
wheel = wheels.get(wheelName, ['?'])
|
||||
v = wheel[0]
|
||||
return (Tuple if v.isdigit() or '?' == v else click)(
|
||||
insertDict(wheelName)(leftRotate(wheel))(wheels)
|
||||
)(v)
|
||||
return go
|
||||
return click(wheelMap)('A')
|
||||
|
||||
|
||||
# leftRotate :: [a] -> String
|
||||
def leftRotate(xs):
|
||||
''' A string shifted cyclically towards
|
||||
the left by one position.
|
||||
'''
|
||||
return ''.join(islice(cycle(xs), 1, 1 + len(xs)))
|
||||
|
||||
|
||||
# ------------------------- TEST -------------------------
|
||||
# main :: IO ()
|
||||
def main():
|
||||
'''First twenty values from each set of test wheels.'''
|
||||
|
||||
wheelMaps = [dict(kvs) for kvs in [
|
||||
[('A', "123")],
|
||||
[('A', "1B2"), ('B', "34")],
|
||||
[('A', "1DD"), ('D', "678")],
|
||||
[('A', "1BC"), ('B', "34"), ('C', "5B")]
|
||||
]]
|
||||
print('New state of wheel sets, after 20 clicks of each:\n')
|
||||
for wheels, series in [
|
||||
mapAccumL(compose(const)(clockWorkTick))(
|
||||
dct
|
||||
)(' ' * 20) for dct in wheelMaps
|
||||
]:
|
||||
print((wheels, ''.join(series)))
|
||||
|
||||
print('\nInital states:')
|
||||
for x in wheelMaps:
|
||||
print(x)
|
||||
|
||||
|
||||
# ----------------------- GENERIC ------------------------
|
||||
|
||||
# Tuple (,) :: a -> b -> (a, b)
|
||||
def Tuple(x):
|
||||
'''Constructor for a pair of values,
|
||||
possibly of two different types.
|
||||
'''
|
||||
return lambda y: (
|
||||
x + (y,)
|
||||
) if isinstance(x, tuple) else (x, y)
|
||||
|
||||
|
||||
# compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
|
||||
def compose(g):
|
||||
'''Right to left function composition.'''
|
||||
return lambda f: lambda x: g(f(x))
|
||||
|
||||
|
||||
# const :: a -> b -> a
|
||||
def const(k):
|
||||
'''The latter of two arguments,
|
||||
with the first discarded.
|
||||
'''
|
||||
return lambda _: k
|
||||
|
||||
|
||||
# insertDict :: String -> a -> Dict -> Dict
|
||||
def insertDict(k):
|
||||
'''A new dictionary updated with a (k, v) pair.'''
|
||||
def go(v, dct):
|
||||
return dict(dct, **{k: v})
|
||||
return lambda v: lambda dct: go(v, dct)
|
||||
|
||||
|
||||
# mapAccumL :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])
|
||||
def mapAccumL(f):
|
||||
'''A tuple of an accumulation and a map
|
||||
with accumulation from left to right.
|
||||
'''
|
||||
def nxt(a, x):
|
||||
tpl = f(a[0])(x)
|
||||
return tpl[0], a[1] + [tpl[1]]
|
||||
|
||||
def go(acc):
|
||||
def g(xs):
|
||||
return reduce(nxt, xs, (acc, []))
|
||||
return g
|
||||
return go
|
||||
|
||||
|
||||
# MAIN ---
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue