15
\$\begingroup\$

For this challenge, we are writing the time in the following form: hh:mm:ss

Some examples:

12:34:08

06:05:30

23:59:00

The challenge is to output the time after an amount of hours, minutes and seconds have elapsed, with as starting time 00:00:00. You can compare this with a timer that started at 00:00:00.

Here is an example of inputs (using STDIN) and outputs:

Input: 1h20m5s
Output: 01:20:05

Input: 0h100m0s
Output: 01:40:00

After 24 hours, the timer resets itself:

Input: 25h0m0s
Output: 01:00:00

The form of the input is always the same: XhYmZs, with X hours, Y minutes and Z seconds (assume that X, Y and Z are whole integers less than 100000 and never negative)

This is , so least amount of bytes wins this challenge

\$\endgroup\$
  • 3
    \$\begingroup\$ Can we write functions? \$\endgroup\$ – LegionMammal978 Oct 25 '15 at 15:37
  • 1
    \$\begingroup\$ @LegionMammal978, yes \$\endgroup\$ – Adnan Oct 25 '15 at 15:59
  • \$\begingroup\$ "assume that X, Y and Z are whole integers less than 99999 and never negative" is 99999h99999m99999s a valid input? \$\endgroup\$ – Cruncher Oct 26 '15 at 17:36
  • \$\begingroup\$ @Cruncher, yes, that is a valid input \$\endgroup\$ – Adnan Oct 26 '15 at 17:37
  • \$\begingroup\$ 99999 is not less than 99999. \$\endgroup\$ – Luke Oct 26 '15 at 18:57

18 Answers 18

4
\$\begingroup\$

CJam, 34 bytes

leu~]2%60b86400%60b3Te[{s2Te[}%':*

Try it here.

\$\endgroup\$
4
\$\begingroup\$

Ruby - 131 115 107 97 84 bytes

I'm still golfing it.

h,m,s=gets.split(/\w/).map &:to_i;$><<"#{(h+m/60+s/3600)%24}:#{(m+s/60)%60}:#{s%60}"

Thanks for @Doorknob for /\w/ inshead of /h|m|s/

\$\endgroup\$
  • \$\begingroup\$ You can split on a regex: gets.tr('ms',?h).split(?h) -> gets.split(/\w/). \$\endgroup\$ – Doorknob Oct 25 '15 at 16:14
  • \$\begingroup\$ @Doorknob I've just rewritten it to regexes but yours is shorter. Thanks! \$\endgroup\$ – Peter Lenkefi Oct 25 '15 at 16:14
  • 1
    \$\begingroup\$ I give up on trying to compete. Mma is just too verbose. \$\endgroup\$ – LegionMammal978 Oct 25 '15 at 16:15
  • 3
    \$\begingroup\$ @LegionMammal978 Never give up ;) \$\endgroup\$ – Peter Lenkefi Oct 25 '15 at 16:17
2
\$\begingroup\$

Mathematica, 133 116 112 111 bytes

IntegerString[(f=FromDigits)[f/@StringSplit[#,_?LetterQ],60]~Mod~86400~IntegerDigits~60,10,2]~StringRiffle~":"&
\$\endgroup\$
2
\$\begingroup\$

Python 2, 138 126 Bytes

Now I'm using regex, still quite long though..

import re
a=input();b=map(int,re.split('h|m|s',a)[:-1])
s=b[0]*3600+b[1]*60+b[2]
print(':%02d'*3)[1:]%(s/3600%24,s/60%60,s%60)

Input should be in quotes.

\$\endgroup\$
2
\$\begingroup\$

C 149 112 bytes

Test it here

main(h,m,s){scanf("%dh%dm%ds",&h,&m,&s);s+=h*3600+m*60;h=s/3600;m=s/60;printf("%02d:%02d:%02d",h%24,m%60,s%60);}

Credits to @Dennis for getting rid of a lot it.

\$\endgroup\$
  • 2
    \$\begingroup\$ main(h,m,s){scanf("%dh%dm%ds",&h,&m,&s);s+=h*3600+m*60;m=s/60;h=m/60;printf("%02d:%02d:%02d",h%24,m%60,s%60);} (110 bytes, reads from STDIN) \$\endgroup\$ – Dennis Oct 25 '15 at 16:40
  • \$\begingroup\$ @Dennis thanks, forgot it didn't have to be a command line argument. The only thing that wasn't working for me was the declaration of the variables in the function argument list; I was getting compiler errors with that. \$\endgroup\$ – Chris Loonam Oct 25 '15 at 17:01
  • \$\begingroup\$ h,m,s;main() should be more portable. main(h,m,s) works with GCC (link) \$\endgroup\$ – Dennis Oct 25 '15 at 17:06
  • \$\begingroup\$ Ok, thanks. Got it down to 112. \$\endgroup\$ – Chris Loonam Oct 25 '15 at 17:08
  • \$\begingroup\$ m=s/60;h=m/60; ? After this you can get rid of the s+= too. \$\endgroup\$ – ugoren Oct 26 '15 at 15:45
2
\$\begingroup\$

JavaScript 110 bytes

Where x is the input

x=x.split(/[hms]/).map(Number);for(z=2;z--;)x[z+1]-60&&(x[z]+=~~(x[z+1]/60));y=x[0]%24+":"+x[1]%60+":"+x[2]%60

I don't think this is the most efficient way

// How it works:
x=x.split(/[hms]/).map(Number);                // splitting the string into an array of numbers
for(z=2;z--;)x[z+1]-60&&(x[z]+=~~(x[z+1]/60)); // shifting excess of seconds to minutes, and then minutes to hours
y=x[0]%24+":"+x[1]%60+":"+x[2]%60              // putting them all together
\$\endgroup\$
2
\$\begingroup\$

PHP, 80 88 93 Bytes

<?=!$s=split(~¤—’¢,fgets(STDIN)),date(~·Å–ÅŒ,$s[0]*3600+$s[1]*60+$s[2]-date(Z));

(saved as ISO-8859-1)

Works only on PHP 5 because of deprecated split function. Assumes that notices are not shown.

How it works:

  • ¤—’¢ is "[hm]" inverted and a valid constant name, PHP uses undefined constants as string (saves one character for the quotation marks)
  • ·Å–ÅŒ is the same for "H:i:s"
  • Everything is a single short handed echo statement. <?=x,y outputs x and y. Using !, the result of the $s assignment gets converted to boolean and negated, then converted to string to output. (string)false === ''
  • split("[hm]", "XhYmZs") splits the string to [X,Y,Zs]. Then, 3600*X+60*Y+Zs is the number of seconds. PHP converts Zs to integer as Z
  • We substract the timezone offset date(Z), use this result as a timestamp and print its time part as "hours:minutes:seconds". In UTC (offset 0), the timestamp 0 is 1970/01/01 00:00:00. Substracting the timezone offset normalizes the date as UTC without changing the actually used timezone (this saved 8 bytes for setting the timezone).
  • Conveniently, 25 hours will result in 01:00:00 (on the next day).
\$\endgroup\$
1
\$\begingroup\$

AutoIt, 208 bytes

Func _($0)
$1=StringRegExp($0,"[0-9]+",3)
For $2=2 To 1 Step -1
If $1[$2]>59 Then
$1[$2]=Mod($1[$2],59)-1
$1[$2-1]+=1
EndIf
Next
Return StringFormat("%02u:%02u:%02u",$1[0]-($1[0]>23?24:0),$1[1],$1[2])
EndFunc

Too long. Test:

ConsoleWrite(_("1h20m5s") & @LF)
ConsoleWrite(_("0h100m0s") & @LF)
ConsoleWrite(_("25h0m0s") & @LF)
\$\endgroup\$
1
\$\begingroup\$

Pyth, 40 bytes

j\:%L"%02d">3j+%ivM:z"\d+"1K60 86400^KTK

I'm still learning. Try it here!

\$\endgroup\$
1
\$\begingroup\$

Perl 5, 84 (83 Bytes + 1)

Uses the overflow of seconds or minutes.

($h,$m,$s)=split/\D/;$h+=($m+=$s/60)/60;printf"%0.2d:%0.2d:%0.2d",$h%24,$m%60,$s%60

Test

$ echo 35:124:224s |perl -n 61736-time-after-some-time.pl
13:07:44
\$\endgroup\$
1
\$\begingroup\$

VBA (150149 bytes)

Function t(s)
x = Split(Replace(Replace(Replace(s, "s", ""), "m", " "), "h", " "))
t = Format(TimeSerial(x(0), x(1), x(2)), "HH:MM:SS")
End Function
\$\endgroup\$
  • 1
    \$\begingroup\$ Looks Good. VBA seems great for this task. If you use msgbox as output you can change to a Sub and save 2 bytes. You can Also Golf away all the unneeded white space around the = and after each , to knock it down around 134. \$\endgroup\$ – JimmyJazzx Oct 26 '15 at 16:35
1
\$\begingroup\$

JavaScript, 97 bytes

x=>([h,m,s]=x.match(/\d+/g),[(+h+m/60|0)%24,(+m+s/60|0)%60,s%=60].map(a=>(a>9?'':'0')+a).join`:`)
\$\endgroup\$
  • \$\begingroup\$ Can you turn this into a Fiddle? Doesn't seem to work for me. I get Invalid left-hand side in assignment \$\endgroup\$ – Gust van de Wal Oct 28 '15 at 10:33
  • \$\begingroup\$ @GustvandeWal So far FireFox is the only browser to support destructuring assignment, so a fiddle won't help unfortunately. \$\endgroup\$ – Mwr247 Oct 29 '15 at 14:50
1
\$\begingroup\$

PowerShell, 84 Bytes

$a=$args-split'[hms]';"{0:HH:mm:ss}"-f(date 0).AddSeconds(3600*$a[0]+60*$a[1]+$a[2])

Splits the command-line input into an array of strings based on the [hms] regex. Uses the verbose built-in function .AddSeconds() to add (hours*3600, minutes*60, and seconds) to (date 0) a/k/a Monday, January 1, 0001, 12:00:00 AM, then feeds that into -f with formatting HH:mm:ss which will automatically convert it to 24-hour clock format and output it.

Example:

PS C:\Tools\Scripts\golfing> .\time-after-some-time.ps1 25h100m0s
02:40:00
\$\endgroup\$
1
\$\begingroup\$

Lua, 104 bytes

h,m,s=io.read():match"(%d+)h(%d+)m(%d+)"m=m+s/60;print(("%02d:%02d:%02d"):format((h+m/60)%24,m%60,s%60))
\$\endgroup\$
1
\$\begingroup\$

VB.NET (107 bytes)

First submission for code golf so I'm guessing character count => byte count?

MsgBox(TimeSpan.Zero.Add(TimeSpan.Parse(Regex.Replace(InputBox("XhYmZs"),"[hm]",":").Trim("s"))).ToString)
\$\endgroup\$
1
\$\begingroup\$

Python 3, 158

import re
e=input()
b=[];p=0
for s in re.split('\D',e)[:3][::-1]:c,a=divmod(int(s),60);b+=[a+p];p=c
b[2]=(b[2]+p)%24;f=':%02d'*3;print(f[1:]%(b[2],b[1],b[0]))

Ungolfed version:

import re
def timer(elapsed):
    base=[]
    previous_carry=0
    for section in re.split('\D+',elapsed)[:3][::-1]:
        carry,amount=divmod(int(section),60)
        base+=[amount+previous_carry]
        previous_carry=carry
    base[2]=(base[2]+previous_carry)%24
    format_str = ':%02d'*3
    return format_str[1:]%(base[2],base[1],base[0])
\$\endgroup\$
1
\$\begingroup\$

CJam, 50 bytes

0[l"hms"Ser~][24 60 60].{md}(;+2/::+{"%02d"e%}%':*
\$\endgroup\$
1
\$\begingroup\$

GNU sed+date, 51 bytes

(including +1 byte for -r flag)

#!/bin/sed -rf
s/(.*h)(.*m)(.*s)/date -d"0:0 \1our\2in\3ec" +%T/e

This simply gets date to add the specified number of hours, minutes and seconds to 00:00:00 (today) and display the time part. Recommended to set TZ=UTC or avoid running the program around a local-time change (e.g. daylight savings).

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.