93 lines
2.2 KiB
Python
93 lines
2.2 KiB
Python
'''Range expansion'''
|
|
|
|
from functools import (reduce)
|
|
|
|
|
|
# rangeExpansion :: String -> [Int]
|
|
def rangeExpansion(s):
|
|
'''List of integers expanded from a
|
|
comma-delimited string of individual
|
|
numbers and hyphenated ranges.
|
|
'''
|
|
def go(a, x):
|
|
tpl = breakOn('-')(x[1:])
|
|
r = tpl[1]
|
|
return a + (
|
|
[int(x)] if not r
|
|
else enumFromTo(int(x[0] + tpl[0]))(
|
|
int(r[1:])
|
|
)
|
|
)
|
|
return reduce(go, s.split(','), [])
|
|
|
|
|
|
# TEST ----------------------------------------------------
|
|
def main():
|
|
'''Expansion test'''
|
|
|
|
print(
|
|
fTable(__doc__ + ':')(
|
|
lambda x: "\n'" + str(x) + "'"
|
|
)(lambda x: '\n\n\t' + showList(x))(
|
|
rangeExpansion
|
|
)([
|
|
'-6,-3--1,3-5,7-11,14,15,17-20'
|
|
])
|
|
)
|
|
|
|
|
|
# GENERIC FUNCTIONS ---------------------------------------
|
|
|
|
# breakOn :: String -> String -> (String, String)
|
|
def breakOn(needle):
|
|
'''A tuple of:
|
|
1. the prefix of haystack before needle,
|
|
2. the remainder of haystack, starting
|
|
with needle.
|
|
'''
|
|
def go(haystack):
|
|
xs = haystack.split(needle)
|
|
return (xs[0], haystack[len(xs[0]):]) if (
|
|
1 < len(xs)
|
|
) else (haystack, '')
|
|
return lambda haystack: go(haystack) if (
|
|
needle
|
|
) else None
|
|
|
|
|
|
# enumFromTo :: (Int, Int) -> [Int]
|
|
def enumFromTo(m):
|
|
'''Integer enumeration from m to n.'''
|
|
return lambda n: list(range(m, 1 + n))
|
|
|
|
|
|
# fTable :: String -> (a -> String) ->
|
|
# (b -> String) ->
|
|
# (a -> b) -> [a] -> String
|
|
def fTable(s):
|
|
'''Heading -> x display function -> fx display function ->
|
|
f -> value list -> tabular string.'''
|
|
def go(xShow, fxShow, f, xs):
|
|
w = max(map(lambda x: len(xShow(x)), xs))
|
|
return s + '\n' + '\n'.join([
|
|
xShow(x).rjust(w, ' ') + (
|
|
' -> '
|
|
) + fxShow(f(x)) for x in xs
|
|
])
|
|
return lambda xShow: lambda fxShow: (
|
|
lambda f: lambda xs: go(
|
|
xShow, fxShow, f, xs
|
|
)
|
|
)
|
|
|
|
|
|
# showList :: [a] -> String
|
|
def showList(xs):
|
|
'''Stringification of a list.'''
|
|
return '[' + ','.join(str(x) for x in xs) + ']'
|
|
|
|
|
|
# MAIN ---
|
|
if __name__ == '__main__':
|
|
main()
|