Convert seconds to compound duration: Difference between revisions
Content deleted Content added
→Python: Functional: Added a variant composing pure curried functions, including mapAccumL |
|||
Line 2,748: | Line 2,748: | ||
6000000 sec = 9 wk, 6 d, 10 hr, 40 min |
6000000 sec = 9 wk, 6 d, 10 hr, 40 min |
||
>>> </lang> |
>>> </lang> |
||
Or, composing a solution from pure curried functions, including the '''mapAccumL''' abstraction (a combination of of '''map''' and '''reduce''', implemented in a variety of languages and functional libraries, in which a new list is derived by repeated application of the same function, as an accumulator (here, a remainder) passes from left to right): |
|||
<lang python>from functools import (reduce) |
|||
from itertools import (chain) |
|||
# main :: IO () |
|||
def main(): |
|||
anglo = durationParts(['wk', 'd', 'hr', 'min', 'sec']) |
|||
for xs in map(anglo, [7259, 86400, 6000000]): |
|||
print ( |
|||
', '.join([ |
|||
str(n) + ' ' + k for n, k in xs |
|||
]) |
|||
) |
|||
# durationParts :: [String] -> Int -> [(String, Num)] |
|||
def durationParts(ks): |
|||
'Duration names -> Number of seconds -> (duration, name) pairs' |
|||
def go(a, km): |
|||
k, m = km |
|||
q, r = divmod(a, m) |
|||
# A tuple of the remainder |
|||
# and a possibly empty list, |
|||
# containing any string for this duration unit. |
|||
return (r, [(q, k)] if 0 < q else []) |
|||
return lambda n: ( |
|||
# concat eliminates any empty lists |
|||
concat( |
|||
# The second part of the tuple only |
|||
# (we no longer need the remainder accumulator) |
|||
mapAccumL(go)(n)( |
|||
zip(ks, [604800, 86400, 3600, 60, 1]) |
|||
)[1] |
|||
) |
|||
) |
|||
# GENERIC ABSTRACTIONS ------------------------------------ |
|||
# concat :: [[a]] -> [a] |
|||
def concat(xs): |
|||
'''This turns out to be the fastest concat in the standard libraries,''' |
|||
'''itertools-independent alternatives can also be written.''' |
|||
return list(chain.from_iterable(xs)) |
|||
# mapAccumL :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y]) |
|||
def mapAccumL(f): |
|||
def go(a, x): |
|||
tpl = f(a[0], x) |
|||
return (tpl[0], a[1] + [tpl[1]]) |
|||
return lambda acc: lambda xs: ( |
|||
reduce(go, xs, (acc, [])) |
|||
) |
|||
if __name__ == '__main__': |
|||
main()</lang> |
|||
{{Out}} |
|||
<pre>2 hr, 59 sec |
|||
1 d |
|||
9 wk, 6 d, 10 hr, 40 min</pre> |
|||
=={{header|Racket}}== |
=={{header|Racket}}== |