# Arbitrary Clock Time Calculator

Create a routine to calculate the position of each unit of a clock with an arbitrary number of units (minutes, hours, half-days, days, years, parsecs, quarter-quells, etc), where each unit can be equally sub-divided into an arbitrary number of sub-units; after n base units have elapsed.

Basically, figure out what a clock would show after n seconds given user defined lengths for minutes, hours, days, etc.

For example, after 86,400 seconds on a clock that has 60 seconds in a minute, 60 minutes in an hour, 12 hours per half day, 2 half days per day, and 365 days in a year; you get the following:

clockFunction(86400,[60,60,12,2,365]) = 0,0,0,0,1  (Standard Clock)

clockFunction(86400,[60,60,12,2]) = 0,0,0,0  (Standard Clock - Rolling Over)

clockFunction(7430201,[100,100,10,10,3,12]) = 1,2,3,4,1,2  (French Republican Calendar [sec / min, min / hr, hrs / day, days / wk, wks / mo, mo / yr])

clockFunction(2443332,[60,60,24,365]) = 12,42,6,28  (Standard Clock - Donnie Darko)

clockFunction(63570500940,[60,60,12,2,365,10000]) = 0, 29, 4, 1, 294, 2015  (Standard Clock - Back to the Future)

Shortest code that works wins!

Clarifications:

• All Units are integer
• All Units are greater than 0
• In none of the test cases does the last conversion seem to matter at all (eg days/year on the standard clocks). Is this intentional? Commented Oct 20, 2015 at 17:53
• I think that's more how I designed the problems. I used that space as a catch all and made it really big so the biggest unit wouldn't roll over. Final unit does matter. I'll add another example. Commented Oct 20, 2015 at 18:01
• Parsecs measure as much time as light-years...none. Commented Oct 20, 2015 at 23:29
• @brandaemon its a dorky tongue-in-cheek reference to Star Wars :-P Commented Oct 21, 2015 at 3:21
• It's in Star Wars all right, but parsecs are a real thing. I'm very particular about my units. Commented Oct 21, 2015 at 4:17

# Dyalog APL, 97 5 bytes

⌽⊤⍨∘⌽


This is a dyadic function train that expects seconds and lengths as left and right arguments. It is equivalent to the following, train-less function:

{⌽⍺⊤⍨⌽⍵}


Verify all test cases at once on TryAPL.

### How it works

    ⌽ Reverse the right argument...
∘    and...
⊤⍨     perform mixed base encoding on the left argument with those bases.
⌽     Reverse the order of the result.

• Unless someone can get in under 5, winner! Can you explain what your code is doing? Commented Oct 20, 2015 at 18:07
• What encoding does this use? Commented Oct 20, 2015 at 19:39
• @Mwr247 There are APL code pages (that predate Unicode by a few decades) where each character is a single byte. Commented Oct 20, 2015 at 19:45
• @Dennis I figured it was single byte, but for the life of me couldn't find any charset that fit them all. Thanks for clearing that up! Commented Oct 20, 2015 at 19:48

# Javascript ES6, 34 bytes

F=(q,a)=>a.map(u=>[q%u|0,q/=u][0])


Explanation:

F=(q,a)=>a.map(u=>
// For each unit
[
q%u|0, // floored remainder of q / u
q/=u // set q to quotient of q / u
][0] // return remainder
)


# CJam, 10 bytes

{{md\}%W<}


Verify all test cases at once in the CJam interpreter.

### How it works

{        }  Define a code block:
{   }%     For each unit length:
md          Perform modular division with the topmost integers on the stack.
\         Swap quotient and residue.
Collect the results in an array.
W<   Discard the last quotient.


# C – 166 176 bytes

The Back to the Future test case necessitated using long long types! The output format is not consistent in the specs, sometimes there are spaces after the comma, sometimes not, I assumed this meant the space was discretionary. Handles units of zero by outputting -1.

#include<stdlib.h>
#include<stdio.h>
int main(int c,char**v){long long x=atoll(*++v),m;while(--c>1){m=atoll(*++v);printf("%lld%c",x%m,c>2?',':'\n');x/=m;}return 0;}


To use, save as units.c, compile via gcc -o units units.c, and run on the command line as follows:

\$ ./units 63570500940 60 60 12 2 365 10000
0,29,4,1,294,2015


Depending on compiler options, you may be able to remove int  and return 0; for 153 bytes.

# MATLAB, 66

function a=d(t,L);a=[];for s=L;a=[a mod(t,s)];t=floor(t/s);end;end


And an explanation

function a=d(t,L)
a=[];
for s=L %For each of the input blocks
a=[a mod(t,s)]; %Append the number in this block
t=floor(t/s); %And divide by the size of this block ignoring the remainder
end
end


It's a pretty standard approach. I'll see if I can reduce the length.

It also works with Octave, so you can try it here.

• I did literally the same thing in javaScript. Was curious if anyone had anything fancier or some obscure math trick (en.wikipedia.org/wiki/Fast_inverse_square_root) to do it with. Commented Oct 20, 2015 at 18:11

# Wolfram Language (Mathematica), 47 bytes

#~NumberDecompose~Reverse@FoldList[Times,1,#2]&


Try it online!

# ><>, 12 bytes

:{:}%:nao-{,


Expect (units...,seconds) on the stack.

><> has the oddball property of supporting floating point division but not integer division, so the verbous stack shifting {} and copying : here is in order to subtract the remainder before performing division.