89 lines
2.2 KiB
Python
89 lines
2.2 KiB
Python
'''Range consolidation'''
|
|
|
|
from functools import reduce
|
|
|
|
|
|
# consolidated :: [(Float, Float)] -> [(Float, Float)]
|
|
def consolidated(xs):
|
|
'''A consolidated list of
|
|
[(Float, Float)] ranges.'''
|
|
|
|
def go(abetc, xy):
|
|
'''A copy of the accumulator abetc,
|
|
with its head range ab either:
|
|
1. replaced by or
|
|
2. merged with
|
|
the next range xy, or
|
|
with xy simply prepended.'''
|
|
if abetc:
|
|
a, b = abetc[0]
|
|
etc = abetc[1:]
|
|
x, y = xy
|
|
return [xy] + etc if y >= b else ( # ab replaced.
|
|
[(x, b)] + etc if y >= a else ( # xy + ab merged.
|
|
[xy] + abetc # xy simply prepended.
|
|
)
|
|
)
|
|
else:
|
|
return [xy]
|
|
|
|
def tupleSort(ab):
|
|
a, b = ab
|
|
return ab if a <= b else (b, a)
|
|
|
|
return reduce(
|
|
go,
|
|
sorted(map(tupleSort, xs), reverse=True),
|
|
[]
|
|
)
|
|
|
|
|
|
# TEST ----------------------------------------------------
|
|
# main :: IO ()
|
|
def main():
|
|
'''Tests'''
|
|
|
|
print(
|
|
tabulated('Consolidation of numeric ranges:')(str)(str)(
|
|
consolidated
|
|
)([
|
|
[(1.1, 2.2)],
|
|
[(6.1, 7.2), (7.2, 8.3)],
|
|
[(4, 3), (2, 1)],
|
|
[(4, 3), (2, 1), (-1, -2), (3.9, 10)],
|
|
[(1, 3), (-6, -1), (-4, -5), (8, 2), (-6, -6)]
|
|
])
|
|
)
|
|
|
|
|
|
# GENERIC FUNCTIONS FOR DISPLAY ---------------------------
|
|
|
|
|
|
# compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
|
|
def compose(g):
|
|
'''Right to left function composition.'''
|
|
return lambda f: lambda x: g(f(x))
|
|
|
|
|
|
# tabulated :: String -> (a -> String) ->
|
|
# (b -> String) ->
|
|
# (a -> b) -> [a] -> String
|
|
def tabulated(s):
|
|
'''Heading -> x display function -> fx display function ->
|
|
f -> value list -> tabular string.'''
|
|
def go(xShow, fxShow, f, xs):
|
|
w = max(map(compose(len)(xShow), 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
|
|
)
|
|
)
|
|
|
|
|
|
# MAIN ---
|
|
if __name__ == '__main__':
|
|
main()
|