Convert seconds to compound duration: Difference between revisions

Content deleted Content added
Dedalus (talk | contribs)
Hout (talk | contribs)
→‎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}}==