code golf explanation

Imagine that line of chars is in fact two rows. Upper row - dots - represents hours (24 hour system), while lower - commas - represents minutes. One character can represent hour, minute or both - whenever it's possible.

At first probably you'd have to convert minutes since midnight to hours and minutes.

The result is the string showing current time in "dot format". The dot count (apostrophe counts here as a dot and will be called so!) is the hour count since midnight and comma count is minutes count. I'll show a few examples to make it clear.

  • (Remark) hh:mm - result
  • (Only hours) 05:00 - '''''
  • (Only minutes) 00:08 - ,,,,,,,,
  • (hours < minutes) 03:07 - ;;;,,,,
  • (hours > minutes) 08:02 - ;;''''''
  • (hours = minutes) 07:07 - ;;;;;;;
  • (the start of the day) 00:00 - (empty result)

Notice that "both" character can be used max 23 times - for 23:xx, where xx is 23 or more.


If character have to (see rule 5.) be escaped in your language, you could changed it to one of alternatives. If said alternatives aren't enough, you may use other symbols - but keep it reasonable. I just don't want escaping to be a barrier.

  • ; (semicolon) - marker for both hours and minutes (alt: :)
  • ' (apostrophe) - marker for hours (alt: '``°)
  • , (comma) - marker for minutes (alt: .)

Additional rules

  1. The code with the least amount of bytes wins!
  2. You have to use both symbol whenever it's possible. For 02:04 the result can't be '',,,,, nor ;',,,. It have to be ;;,,
  3. Input - can be script/app parameter, user input (like readline) or variable inside code
    3.1. If the variable inside code is used, then its lenght have to be the longest possible. It's 1439 (23:59), so it would look like t=1439
  4. The common part which is symbolized by "both" character (12 in 12:05, 3 in 03:10) must be placed on the beginning of the string
  5. Symbols can be replaced to alternatives only if they would have to be escaped in your code.
  6. Input is given in minutes after 00:00. You can assume that this is a non-negative integer.

Test cases

Input: 300
Output: '''''

Input: 8
Output: ,,,,,,,,

Input: 187
Output: ;;;,,,,

Input: 482
Output: ;;''''''

Input: 427
Output: ;;;;;;;

Input: 0
Output:  (empty)
  • 3
    \$\begingroup\$ No problem! It is a very good first post and a nice challenge :) \$\endgroup\$
    – Adnan
    Commented Dec 23, 2015 at 2:45
  • 1
    \$\begingroup\$ this looks so good with just semicolons and commas, but apostrophes muck it all up :( \$\endgroup\$
    – Sparr
    Commented Dec 23, 2015 at 2:55
  • \$\begingroup\$ Actually 1439 is 23:59 and not 1339. (23 x 60 + 59). \$\endgroup\$ Commented Dec 23, 2015 at 9:04
  • \$\begingroup\$ Thank all of you for good words! :) @Sparr, yeah, that's the bad point :( Have you idea how it could be replaced? insertusernamehere, of course that's right! Fixed :) \$\endgroup\$
    – Krzysiu
    Commented Dec 23, 2015 at 18:33
  • \$\begingroup\$ 3.1 is kind of weird... What does it mean? Does the variable have to be called qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq? \$\endgroup\$
    – user46167
    Commented Dec 23, 2015 at 21:45

26 Answers 26


Pyth, 19 bytes


Test suite

      .DQ60            Divmod the input by 60, giving [hours, minutes].
           J"',"       Set J equal to the string "',".
    *V                 Perform vectorized multiplication, giving H "'" and M ','.
 .iF                   Interleave the two lists into a single string.
:               J\;    Perform a substitution, replacing J with ';'.

CJam, 22 20 19 bytes

Takes input from STDIN:


Test it here.


ri     e# Read input and convert to integer.
60md   e# Divmod 60, pushes hours H and minutes M on the stack.
]      e# Wrap in an array.
',`    e# Push the string representation of the comma character which is "',".
.*     e# Repeat apostrophe H times and comma M times.
:.{    e# Apply this block between every pair of characters. This will only applied to
       e# first N characters where N = min(hours,minutes). The others will remain
       e# untouched. So we want the block to turn that pair into a semicolon...
  ;    e#   Discard the comma.
  K+   e#   Add 20 to the apostrophe to turn it into a semicolon.

It was really lucky how well things worked together here, in particular the assignment of hours to ' and minutes to , such that the order of hours and minutes on the stack matched up with the string representation of the character.

This is the only 3-byte block I've found so far. There were tons of 4-character solutions though:


GNU Sed, 37

Score includes +1 for -E option to sed.

I wasn't particularly impressed with the golfiness of my bash answer, so I thought I'd try with sed for the fun.

Input is in unary, as per this meta-answer.

y/1/,/          # Convert unary 1's to commas (minutes)
s/,{60}/'/g     # divmod by 60.  "'" are hours
:               # unnamed label
s/(.*)',/;\1/   # replace an apostrophe and comma with a semicolon
t               # jump back to unnamed label until no more replacements

Try it online

  • \$\begingroup\$ unnamed label?? \$\endgroup\$
    – mikeserv
    Commented Dec 23, 2015 at 7:32
  • \$\begingroup\$ @mikeserv, see Digital Trauma's related tip in Tips for golfing in sed. \$\endgroup\$
    – manatwork
    Commented Dec 23, 2015 at 12:26
  • \$\begingroup\$ @manatwork - i think it must be a GNU bug. \$\endgroup\$
    – mikeserv
    Commented Dec 23, 2015 at 18:12
  • \$\begingroup\$ @mikeserv - but using bugs is OK as well, right? I'm not asking to mock you, I just don't know :) \$\endgroup\$
    – Krzysiu
    Commented Dec 23, 2015 at 18:40
  • \$\begingroup\$ @Krzysiu - ok? hmm. on this site i think it would be a mark of excellence. otherwise, almost definitely no. when programmers stray from API and use implementation details programs become version/implementation dependent - which is a bad thing. \$\endgroup\$
    – mikeserv
    Commented Dec 23, 2015 at 18:59

Python 2, 56 bytes

def g(t):d=t%60-t/60;print(t/60*";")[:t%60]+","*d+"'"*-d

A function that prints (one char shorter than t=input();).

The method is similar to Loovjo's. The number of , is the different between minutes and hours, with an implicit minimim of 0. For ', it's the negation. For ;, computes the min implicitly by taking as many ; as hours, then truncating to the number of minutes.

It saves chars to save d, but not the number of hours and minutes here. The analogue with lambda was two chars longer (58), so the variable assignments are worth it.

lambda t:(t%60*";")[:t/60]+","*(t%60-t/60)+"'"*(t/60-t%60)

Processing the input directly didn't save chars either (58):


Another strategy with slicing, much longer (64):

def g(t):m=t%60;h=t/60;return(";"*m)[:h]+(","*m)[h:]+("'"*h)[m:]

Retina, 24

Trivial port of my sed answer.

Input is in unary, as per this meta-answer.


Try it online.


Pure Bash (no external utilities), 103

p()(printf -vt %$2s;printf "${t// /$1}")
p \; $[h=$1/60,m=$1%60,m>h?c=m-h,h:m]
p , $c
p \' $[m<h?h-m:0]

Thanks to @F.Hauri for saving 2 bytes.

  • \$\begingroup\$ Nice! But you could save 2 chars by swapping $1 and $2 in p() and write p , $c at line 3. \$\endgroup\$ Commented Dec 23, 2015 at 21:03
  • \$\begingroup\$ Yes, but as it's used only in a printf "%s", having c empty will work fine (while not reused) \$\endgroup\$ Commented Dec 24, 2015 at 7:35
  • \$\begingroup\$ @F.Hauri Now I get it - thanks! \$\endgroup\$ Commented Dec 24, 2015 at 22:43

C, 119 bytes

#define p(a,b) while(a--)putchar(b);


// macro: print b, a times
#define p(a,b) while(a--)putchar(b)

int main(void)
    int h,m,n;
    scanf("%d",&m);  // read input

    h=m/60;m%=60;    // get hours:minutes
    n=h<m?h:m;       // get common count
    h-=n;m-=n;       // get remaining hours:minutes

    p(n,59);        // print common
    p(h,39);        // print remaining hours
    p(m,44);        // print remaining minutes

    return 0;
  • 1
    \$\begingroup\$ Using putchar & integer literals as characters saves one byte, pulling the semicolons inside the macro saves two more :) \$\endgroup\$
    – Quentin
    Commented Dec 23, 2015 at 22:35
  • \$\begingroup\$ @Quentin note taken, saved 5 bytes \$\endgroup\$
    – Khaled.K
    Commented Dec 24, 2015 at 7:09
  • \$\begingroup\$ You can lose the space before your while in your #define macro. -1 byte \$\endgroup\$ Commented Mar 2, 2017 at 8:41
  • 1
    \$\begingroup\$ You can also save some more bytes by just making p(a,b) a function instead of a macro. (And sprinkling a few more semi-colons to your main function) \$\endgroup\$ Commented Mar 2, 2017 at 8:48

Haskell, 68 66 Bytes

g(h,m)=id=<<zipWith replicate[min h m,h-m,m-h]";',"

Usage example:

(g.(`divMod`60)) 482

The clever bit here is that replicate will return the empty string if the length given is negative or zero so I can apply it to both differences and only the positive one will show up. The first part is easy, since the number of semicolons is just the minimum of the two. Then zipWith applies the function to the corresponding items.

EDIT: Realized I was using the wrong char for minutes

EDIT 2: Saved 2 bytes thanks to @Laikoni

  • \$\begingroup\$ You can save two bytes by replacing concat$ with id=<<. \$\endgroup\$
    – Laikoni
    Commented Mar 2, 2017 at 8:38

JavaScript (ES6) 69


Powershell, 99 85 bytes


Using Loovjo's method, this is my powershell implementation.


# set the number of minutes and hours, and a boolean which one is bigger
# and also output the correct number of ;s
# add the difference between h and m as 's but only if h > m
# add the difference between m and h as ,s but only if m > h

Saved 14 bytes thanks to AdmBorkBork

  • \$\begingroup\$ You can save by using a pseudo-ternary for the first one, moving the $m and $h declarations into it, and then using Boolean multiplication. Like so -- param($n)';'*(($m=$n%60),($h=$n/60))[($b=$m-gt$h)]+'°'*(($h-$m)*!$b)+','*(($m-$h)*$b) \$\endgroup\$ Commented Mar 2, 2017 at 14:01

Python 3, 98 bytes

if m>=h:print(";"*h+","*(m-h))

Probably not the best answer, but it was a lot of fun!


Python 2, 61 bytes



t=input();              # Read input
          m,  t%60,     # Do a divmod, h = div, m = mod
            h=     t/60

print";"*min(h,m)+                    # Print the minimum of the h and m, but in ";"s
                  ","*(m-h)+          # Print (m-h) ","s (if m-h is negative, print nothing)
                            "'"*(h-m) # Print (h-m) "'"s (if h-m is negative, print nothing)

PHP, 81 bytes

I went for the variable input as it is shorter than reading from STDIN or taking command line arguments.

  • \$\begingroup\$ I thought that I know PHP rather well, but I see | for the first time. I think I'll use it to exercise a bit - I'll analyze it :) \$\endgroup\$
    – Krzysiu
    Commented Dec 23, 2015 at 18:38
  • \$\begingroup\$ Fails for 240. Try $i>=min($h,$m)?$h<$m?",":"'":";" (+1 byte). Or use for($_=1439;$i<max($h=0|$_/60,$m=$_%60);)echo"',;"[$i++<min($h,$m)?2:$h<$m]; (76 bytes). Btw: single quote renders -r impossible; so you should use backtick for hours if in a string or ° standalone (needs no quotes -> -1 byte). \$\endgroup\$
    – Titus
    Commented Mar 1, 2017 at 16:10

JavaScript (ES6), 77 71 bytes

  • \$\begingroup\$ Great use of assignments in attribute access/function arguments. +1 \$\endgroup\$
    – Cyoce
    Commented Mar 2, 2017 at 1:48

Perl 6, 103 101 98 97 69 bytes

$_=get;say ";"x min($!=($_-$_%60)/60,$_=$_%60)~"'"x $!-$_~","x $_-$!;

Outputs several arrays, but fuck it, enjoy. As usual, any golfing oppertunities are appericated.

Edit: -2 bytes: got brave and removed some casts.

Edit2: -3 bytes by removing the arrays.

Edit3: -1 byte to print in right format, using "lambdas" and removing parantheses.

Edit4: (sorry guys) abusing that hours - minutes should return 0 and the opposite. Removed if statements. Then removing brackets, then realising i didnt need the lambda at all. -28 bytes :)

Woah im getting better at this.


C, 141 bytes

main(h,m){scanf("%d",&m);h=(m/60)%24;m%=60;while(h||m){if(h&&m){printf(";");h--;m--;}else if(h&&!m){printf("'");h--;}else{printf(",");m--;}}}
  • \$\begingroup\$ I think you could save a few bytes by using h>0||m>0. Then you need to h--;m--; only once in every iteration and the {} for if/else would get obsolete. \$\endgroup\$ Commented Dec 23, 2015 at 8:57
  • \$\begingroup\$ You can also save a few bytes on your second conditional: instead of else if(h&&!m) you can just have else if(h) \$\endgroup\$
    – Hellion
    Commented Dec 23, 2015 at 19:57
  • \$\begingroup\$ And finally try to use the ternary operator, it will save you from using "long" words like if and else. \$\endgroup\$ Commented Dec 23, 2015 at 21:14
  • \$\begingroup\$ Consider refactoring as a function that takes the input as an int parameter - that should at least save you the scanf(). \$\endgroup\$ Commented Dec 25, 2015 at 0:57
  • \$\begingroup\$ I don't think the %24 is necessary - max input is 23:59. \$\endgroup\$ Commented Dec 25, 2015 at 0:58

Gema, 119 characters


Sample run:

bash-4.3$ gema '<D>=@set{h;@div{$0;60}}@set{m;@mod{$0;60}}@repeat{@cmpn{$h;$m;$h;$h;$m};\;}@repeat{@sub{$h;$m};`}@repeat{@sub{$m;$h};,}' <<< '252'

Matlab: 89 bytes



ans =

SmileBASIC, 59 bytes



HOURS=MINUTES DIV 60 'separate the hours and minutes
PRINT ";"*MIN(HOURS,MINUTES); 'print ;s for all positions with both
PRINT ",'"[MINUTES<HOURS]*ABS(HOURS-MINUTES) 'print extra ' or ,

It looks pretty terrible, since the bottom part of ; is not even the same as , in SmileBASIC's font


PHP, 81 bytes

some more solutions:

// or

Run with echo <time> | php -R '<code>'.

// or
// or

Replace 1439 with input, save to file, run.


Ruby, 50 characters


Thanks to:

  • G B for
    • reminding me that I can't take more characters from a string than it has (-1 character)
    • reorganizing my calculation (-1 character)

Waited so long to use Numeric.divmod, just to realize that its horribly long.

Sample run:

2.1.5 :001 > puts ->t{(?;*h=t/60)[0,m=t%60]+",',"[0<=>m-=h]*m.abs}[252]
  • 1
    \$\begingroup\$ Save 1 character by truncating the string instead of using min: (?;*h=t/60)[0,m=t%60] \$\endgroup\$
    – G B
    Commented Mar 2, 2017 at 12:23
  • 1
    \$\begingroup\$ And another byte by subtracting h from m: ",',"[0<=>m-=h]*m.abs \$\endgroup\$
    – G B
    Commented Mar 2, 2017 at 12:40

05AB1E, 25 bytes


Try it online!

60‰vy„'.Nè×} can definitely be shortened, I just couldn't figure it out, and doubt I'll be able to shave off 7 bytes to win with this approach unless there's a vectored version of ×.

Example (With input equal to 63):

60‰                       # Divmod by 60.
                          # STACK: [[1,3]]
   vy      }              # For each element (probably don't need the loop)...
                          # STACK: []
     „'.Nè×               # Push n apostrophe's for hours, periods for minutes.
                          # STACK: ["'","..."]
            ‚             # Group a and b.
                          # STACK: [["'","..."]]
             .B           # Boxify.
                          # STACK: [["'  ","..."]]
               ø          # Zip it (Transpose).
                          # STACK: [["'."," ."," ."]
                J         # Join stack.
                          # STACK: ["'. . ."]
                 „'.';:   # Replace runs of "'." with ";".
                          # STACK: ["; . ."]
                       ðK # Remove all spaces.
                          # OUTPUT: ;..

D60÷''×s60%'.ׂ.BøJ„'.';:ðK was my original version, but that's even MORE costly than divmod.

60‰WDµ';ˆ¼}-¬0Qi'.ë''}ZׯìJ yet another method I tried...


dc, 95 bytes


Try it online!


Java 8, 101 99 86 bytes

n->{String r="";for(int m=n%60,h=n/60;h>0|m>0;r+=h--*m-->0?";":h<0?",":"'");return r;}


Try it here.

n->{                      // Method with integer parameter and String return-type
  String r="";            //  Result-String (starting empty)
  for(int m=n%60,h=n/60;  //   Get the minutes and hours from the input integer
      h>0|m>0;            //   Loop as long as either the hours or minutes is above 0
    r+=                   //   Append the result-String with:
       h--*m-->0?         //    If both hours and minutes are above 0
                          //    (and decrease both after this check):
        ";"               //     Use ";"
       :h<0?              //    Else-if only minutes is above 0 (hours is below 0)
        ","               //     Use ","
       :                  //    Else:
        "'"               //     Use "'"
  );                      //  End loop
  return r;               //  Return the result
}                         // End of method

///, 49 bytes


Try it online!

The first two substitutions, /x/1111111111//xxxxxx/o/, replace sequences of 60 1s with an o.

/oo1/o1o/ interweaves the 1s into the os, which are next to each other. Ex. oooooo1111111111 -> o1o1o1o1o1o11111 This pairs each o, which is one hour, with one 1, which is minute. This also pushes the 1s to the left, so whichever one is greater is left at the right.

o1/;/ replaces each pair with a ;

/o/'/ /1/1/ and this converts the leftovers to :s or 's


Jelly, 13 bytes


Try it online!


d60ؽẋ"Sị“',;   Main monadic link
d60             Divmod by 60
      "         Zipmap
   ؽ             [1, 2]
                  with that
     ẋ            using the “repeat n times” operator
       S        Sum
        ị       Index into
         “',;   "',;"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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