Task

Write a function or program which:

   takes a positive integer representing a duration in seconds as input (e.g., 100), and
   returns a string which shows the same duration decomposed into:
   weeks,
   days, 
   hours, 
   minutes,   and 
   seconds.
This is detailed below (e.g., "2 hr, 59 sec").



Demonstrate that it passes the following three test-cases:

Test Cases


 input number

 output string


 7259

 2 hr, 59 sec


 86400

 1 d


 6000000

 9 wk, 6 d, 10 hr, 40 min

Details
The following five units should be used:



 unit

 suffix used in output

 conversion


 week

 wk

 1 week = 7 days


 day

 d

 1 day = 24 hours


 hour

 hr

 1 hour = 60 minutes


 minute

 min

 1 minute = 60 seconds


 second

 sec



However, only include quantities with non-zero values in the output (e.g., return "1 d" and not "0 wk, 1 d, 0 hr, 0 min, 0 sec").

Give larger units precedence over smaller ones as much as possible (e.g., return 2 min, 10 sec and not 1 min, 70 sec or 130 sec)

Mimic the formatting shown in the test-cases (quantities sorted from largest unit to smallest and separated by comma+space; value and unit of each quantity separated by space).




 
-module(convert_seconds).
 
-export([test/0]).
 
test() ->
	lists:map(fun convert/1, [7259, 86400, 6000000]),
	ok.
 
convert(Seconds) ->
	io:format(
		"~7s seconds = ~s\n",
		[integer_to_list(Seconds), compoundDuration(Seconds)] ). 
 
% Compound duration of t seconds.  The argument is assumed to be positive.
compoundDuration(Seconds) ->
	intercalate(
		", ", 
		lists:map(
			fun({D,L}) -> io_lib:format("~p ~s",[D, L]) end,
			compdurs(Seconds) ) ).
 
% Time broken down into non-zero durations and their labels.
compdurs(T) ->
	Ds = 
		reduceBy(
			T, 
			lists:map(
				fun(Dl) -> element(1,Dl) end, 
				tl(durLabs()) ) ),
	lists:filter(
			fun(Dl) -> element(1,Dl) /= 0 end,
			lists:zip(
				Ds, 
				lists:map(
					fun(Dl) -> element(2,Dl) end, 
					durLabs() ) ) ).
 
% Duration/label pairs.
durLabs() ->
	[
		{undefined, "wk"}, 
		{7, "d"}, 
		{24, "hr"}, 
		{60, "min"}, 
		{60, "sec"}
	].
 
reduceBy(N, Xs) ->
	{N_, Ys} = mapaccumr(fun quotRem/2, N, Xs),
	[N_ | Ys].
 
quotRem(X1, X2) ->
	{X1 div X2, X1 rem X2}.
 
% **************************************************
% Adapted from http://lpaste.net/edit/47875
% **************************************************
 
mapaccuml(_,I,[]) -> 
	{I, []};
mapaccuml(F,I,[H|T]) -> 
	{Accum, NH} = F(I,H), 
	{FAccum, NT} = mapaccuml(F,Accum,T),
	{FAccum, [NH | NT]}.
 
mapaccumr(_,I,[]) -> 
	{I, []};
mapaccumr(F,I,L) -> 
	{Acc, Ys} = mapaccuml(F,I,lists:reverse(L)),
	{Acc, lists:reverse(Ys)}.
 
% **************************************************
 
 
% **************************************************
% Copied from https://github.com/tim/erlang-oauth/blob/master/src/oauth.erl
% **************************************************
 
intercalate(Sep, Xs) ->
  lists:concat(intersperse(Sep, Xs)).
 
intersperse(_, []) ->
  [];
intersperse(_, [X]) ->
  [X];
intersperse(Sep, [X | Xs]) ->
  [X, Sep | intersperse(Sep, Xs)].
 
% **************************************************
 