27
\$\begingroup\$

I can have a large if/else condition for each 30 minutes but I'm looking for more math and Unicode based solution.

Here are clock emojis: πŸ•πŸ•‘πŸ•’πŸ•“πŸ•”πŸ••πŸ•–πŸ•—πŸ•˜πŸ•™πŸ•šπŸ•›πŸ•œπŸ•πŸ•žπŸ•ŸπŸ• πŸ•‘πŸ•’πŸ•£πŸ•€πŸ•₯πŸ•¦πŸ•§. If you lack proper rendering support, you can see them below (they're not in the same order and they may look different to what you see) or at the Unicode chart, page 4. They correspond to Unicode codepoints U+1F550 (CLOCK FACE ONE OCLOCK) through U+1F567 (CLOCK FACE TWELVE-THIRTY).

Your challenge is to write a program that outputs to STDOUT the closest clock face emoji to the current system time (AM and PM should be treated the same). For example if the time t is [5:15 ≀ t < 5:45), you would display the 5:30 emoji πŸ• .

This is code-golf, so shortest code in bytes wins. You may want to include a way to easily specify the time to test your code.

Edge test cases

Time   Output  Written
----------------------
11:48  πŸ•›       12:00
3:15   πŸ•ž       3:30
9:45   πŸ•™       10:00

enter image description here

\$\endgroup\$
14
  • 8
    \$\begingroup\$ This question isn't currently on-topic here but it's probably an easy fix. You need an objective win condition, but if you tag the question code-golf the winner will be whoever writes the shortest program. It's also a bit under specified, but you could say "a script that outputs the clock emoji closest to the current time when run" and that should be enough. Also, while not technically required, I'd recommend that you allow submissions in other languages. (Someone will probably do one in Bash anyway.) \$\endgroup\$ Commented Dec 10, 2014 at 20:07
  • \$\begingroup\$ Windows Command prompt doesn't support emojis :( \$\endgroup\$
    – stokastic
    Commented Dec 10, 2014 at 20:48
  • 2
    \$\begingroup\$ I've edited your post to attempt to have it meet our standards by clarifying the rules and making it code golf. Feel free to edit it if I misinterpreted anything. \$\endgroup\$ Commented Dec 11, 2014 at 3:44
  • 5
    \$\begingroup\$ How should xx:15 and xx:45 be rounded? \$\endgroup\$ Commented Dec 11, 2014 at 8:35
  • 1
    \$\begingroup\$ @PeterTaylor As seen in the test cases, they should be rounded up (i.e. 1:45 => 2:00) \$\endgroup\$ Commented Dec 11, 2014 at 12:53

11 Answers 11

11
\$\begingroup\$

Ruby β€” 61 54 bytes

Python 3 β€” 79 77 75 74 bytes

edit: Turns out this is much shorter in Ruby, because Time doesn't need to be imported and integer division is the default.

a=(Time.now.to_i/900-3)/2%24
puts""<<128336+a/2+a%2*12

Arithmetic:

  • Time.now.to_i: Seconds since epoch.
  • /900: Combine time into 15-minute segments.
  • -3: -4 because characters start at 1 o'clock, +1 so that rounding is done to nearest half hour, rather than downwards.
  • /2: Combine into half-hour segments.
  • %24: Get current half-hour segment out of 12 hours.
  • a/2 + a%2*12: Account for the fact that whole-hour characters come in a block before half-hour characters.

Local time version, 69 bytes:

n=Time.now
a=((n.to_i+n.gmtoff)/900-3)/2%24
puts""<<128336+a/2+a%2*12

Original Python 3 version:

import time
a=int((time.time()/900-3)/2%24)
print(chr(128336+a//2+a%2*12))

Prints the current time UTC. Python 2's chr only accepts 0-255, and unichr only 0-65535. In Python 3, / is always floating-point division and // is always integer division.

\$\endgroup\$
1
  • \$\begingroup\$ You can cut the parens from 12*(a%2) if you do it in the other order: a%2*12. \$\endgroup\$
    – xnor
    Commented Dec 12, 2014 at 5:11
10
\$\begingroup\$

Bash + Coreutils, 60 47

date +%I\ 60*%M+45-30/24%%2~C*+16iF09F9590+P|dc

Try it online!

Emojis render fine on the OSX terminal, but for Linux (Ubuntu 14.04) you'll have to sudo apt-get install ttf-ancient-fonts

For testing different times, insert -d $time into the date command. e.g for testing 12:59:

date -d 12:59 +%I\ 60*%M+45-30/24%%2~C*+16iF09F9590+P|dc
\$\endgroup\$
6
\$\begingroup\$

CJam, 31 bytes

"πŸ•")et5<60b675+30/24%2mdC*++

You can change the time in the following program to test it:

"πŸ•")[2014 12 19 22 14 1 901 5 -28800000]5<60b675+30/24%2mdC*++
\$\endgroup\$
6
\$\begingroup\$

JavaScript – 137 117 107 102 95 bytes

This is going to get easily beaten, but I'll just try my best here.

EDIT 1: Now prints in UTC like the Python answer to save 20 bytes.

EDIT 2: Changed new Date().getTime() to Date.now() to save 10 bytes.

EDIT 3: Changed Math.round(x) to ~~(x+.5) to save 5 bytes.

EDIT 4: Removed unnecessary ( and &1023) left from some old development version where I did a more universal UTF-16 encoding to save 7 bytes.

d=~~(Date.now()/18e5+.5)%24;d+=d<2?24:0;alert(String.fromCharCode(55357,56655+(d%2?23+d:d)/2));

JavaScript does allow for emojis, but in UTF-16 which encodes them as two characters. Luckily, we can simply define them as two characters; the first character is also constant (0xD83D), while the other changes.

Alternative, prints in local time, 137 132 125:

a=new Date();d=~~(a.getHours()%12*2+a.getMinutes()/30+.5);d+=d<2?24:0;alert(String.fromCharCode(55357,56655+(d%2?23+d:d)/2));

\$\endgroup\$
1
  • 2
    \$\begingroup\$ Isn't (d%2?23+d:d) the same as d+d%2*23? \$\endgroup\$
    – Neil
    Commented Feb 27, 2017 at 15:31
4
\$\begingroup\$

CJam, 50 bytes

"πŸ•":i~et3=C%60*et4=+30d/mo2m24+24%_2%24*+2/+]:c

The algorithm is simple, round the time to nearest 30 minutes, count how many 30 minutes have passed since 12 AM/PM, if the number is odd, then add 24 to it, floor divide by 2 and increment the initial unicode by that many code points to get the right clock face.

Also, make sure that you start with 1 AM/PM instead of 12 so take an offset there.

For testing purposes, use the following code:

3:H;45:M;"πŸ•":i~HC%60*M+30d/mo2m48+48%_2%24*+2/+]:c

Where the 3:H; part is the current hour and the 45:M; part is the current minute of the hour. Simply replace 3 and 45 with the desired value.

Try it online here

Not all unicode characters might print correctly on the online version depending upon your browser and OS and installed fonts. But for me, all print fine on Firefox with Windows 7.

\$\endgroup\$
1
  • \$\begingroup\$ @user23013 Nice!. I think you should post that as a new answer as I did not do any golfing in that :) \$\endgroup\$
    – Optimizer
    Commented Dec 19, 2014 at 14:08
1
\$\begingroup\$

05AB1E, 30 bytes

ΕΎa60*ΕΎb+45-30Γ·24%2‰`12*+Žü€·+Γ§

Port of @jimmy23013's CJam answer, so make sure to upvote him as well!

Try it online or verify some manual test times.

Explanation:

Uses the following formula to calculate the clock codepoint based on the given \$h\$ours and \$m\$inutes:

$$d(h,m) = \left\lfloor\frac{60h+m-45}{30}\right\rfloor\bmod{24} \\ C(h,m) = \left\lfloor\frac{d(h,m)}{2}\right\rfloor+12(d(h,m)\bmod{2})+128336$$

ΕΎa                              # Push the current hours
  60*                           # Multiply them by 60
     ΕΎb+                        # Add the current minutes
        45-                     # Subtract 45
           30Γ·                  # Integer-divided by 30
              24%               # Modulo 24
                 2‰             # Divmod by 2: [n//2,n%2]
                   `            # Pop and push n//2 and n%2 separated to the stack
                    12*         # Multiply n%2 by 12
                       +        # Add it to the n//2
                        Ε½ΓΌΒ€     # Push compressed integer 64168
                           Β·    # Double it to 128336
                            +   # Add it as well
                             Γ§  # Convert it to a character with this codepoint
                                # (after which the result is output implicitly)

See this 05AB1E tip of mine (section How to compress large integers?) to understand why Ε½ΓΌΒ€ is 64168 (compressed 128336 directly is 1 byte longer: β€’1ΓΉΞΈβ€’).

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

C (gcc) with -m32, 104 100 98 bytes

  • -6 thanks to ceilingcat
*t;f(i){char a[]="πŸ•";time(&i);i=1[t=gmtime(&i)]/15;a[3]=144+(t[2]+11+i/4)%12+(i-1U<2)*12;puts(a);}

Try it online!

Ungolfed:

*t; // broken-down time structure ([1]=minutes, [2]=hours)
f(i){ // time
  char a[]="πŸ•"; // base emoji in modifiable UTF-8 string
  time(&i); // get time and convert into structure
  i=1[t=gmtime(&i)]/15; // get granular 15-minute chunks
  a[3]=
    144+ // base 4th byte of emoji
    (t[2]+11+i/4)%12+ // convert [0..23] to [1..24]-1 for hour, adding [0:45..1:00)
    (i-1U<2)*12; // add [0:15..0.45) as half-hour
  puts(a);
}
\$\endgroup\$
1
  • \$\begingroup\$ there might be an error, I got πŸ•› at 12:57 \$\endgroup\$
    – MarcMush
    Commented Oct 13, 2023 at 13:20
1
\$\begingroup\$

Go, 265 bytes, function

import."time"
func f()rune{N,H:=Now(),Hour/2
e,l:=N.Truncate(H),N.Round(H)
if e.Sub(N).Abs()<l.Sub(N).Abs(){N=e}else{N=l}
return []rune("πŸ•›πŸ•§πŸ•πŸ•œπŸ•‘πŸ•πŸ•’πŸ•žπŸ•“πŸ•ŸπŸ•”πŸ• πŸ••πŸ•‘πŸ•–πŸ•’πŸ•—πŸ•£πŸ•˜πŸ•€πŸ•™πŸ•₯πŸ•šπŸ•¦")[N.Hour()%12*2+N.Minute()/30]}

Attempt This Online!

Gets the current time, rounds up and down to the nearest half hour, finds the closer one, and returns the emoji that represents it.

Go, 285 bytes, full program

package main
import."time"
func main(){N,H:=Now(),Hour/2
e,l:=N.Truncate(H),N.Round(H)
if e.Sub(N).Abs()<l.Sub(N).Abs(){N=e}else{N=l}
print(string([]rune("πŸ•›πŸ•§πŸ•πŸ•œπŸ•‘πŸ•πŸ•’πŸ•žπŸ•“πŸ•ŸπŸ•”πŸ• πŸ••πŸ•‘πŸ•–πŸ•’πŸ•—πŸ•£πŸ•˜πŸ•€πŸ•™πŸ•₯πŸ•šπŸ•¦")[N.Hour()%12*2+N.Minute()/30]))}

Attempt This Online!

\$\endgroup\$
1
  • \$\begingroup\$ You have a rogue ) at the end of your first answer. Remove it for 265 bytes \$\endgroup\$
    – The Thonnu
    Commented Apr 6, 2023 at 10:10
1
\$\begingroup\$

Julia, 81 bytes

using Dates
n=now()
M=minute(n)
print('πŸ•'+mod1(hour(n)+(M>44),12)+12(14<M<45))

Attempt This Online!

Julia is generally picky with types, but some common arithmetic statements involving Char, Int, and Bool are permitted. The Int values of the clock emojis are the range 128336:128359. The emojis are encoded in ascending order, with all the twelve that are on the hour coming before the twelve half-past emojis. In this algorithm, the preceding character 'πŸ•' is incremented by the 12-hour number (plus 1 if it's more than 44 minutes past the hour), and another 12 is added if the minute hand needs to be adjusted.

-17 bytes (!!) thanks to MarcMush: just use Dates.minute instead of parsing the time string

\$\endgroup\$
1
  • 1
    \$\begingroup\$ 81 bytes also fixes an error with 12:50 \$\endgroup\$
    – MarcMush
    Commented Oct 13, 2023 at 13:18
0
\$\begingroup\$

Pascal, 134 characters

This program requires a processor supporting the time-related features defined by ISO standard 10206 β€œExtended Pascal”. Furthermore the implementation-defined set of char values must include said Unicode characters.

program t(output);var t:timeStamp;begin getTimeStamp(t);write(('πŸ•›πŸ•§πŸ•πŸ•œπŸ•‘πŸ•πŸ•’πŸ•žπŸ•“πŸ•ŸπŸ•”πŸ• πŸ••πŸ•‘πŸ•–πŸ•’πŸ•—πŸ•£πŸ•˜πŸ•€πŸ•™πŸ•₯πŸ•šπŸ•¦')[t.hour mod 12*2+round(t.minute/30)+1])end.

Ungolfed:

program clock(output);
    var
        ts: timeStamp;
    begin
        getTimeStamp(ts);
        { This `program` presumes `ts.timeValid` is set to `true`. 
          Otherwise `getTimeStamp` sets the clock to midnight. Insert
          
            ts.hour := 11;
            ts.minute := 48;
        
          here to test the functionality of this `program`. }
        writeLn(('πŸ•›πŸ•§πŸ•πŸ•œπŸ•‘πŸ•πŸ•’πŸ•žπŸ•“πŸ•ŸπŸ•”πŸ• πŸ••πŸ•‘πŸ•–πŸ•’πŸ•—πŸ•£πŸ•˜πŸ•€πŸ•™πŸ•₯πŸ•šπŸ•¦')
            [ts.hour mod 12 * 2 + round(ts.minute / 30) + 1]);
    end.
\$\endgroup\$
0
\$\begingroup\$

Wolfram Language (Mathematica), 98 bytes

Print@FromCharacterCode[128336+Quotient[#,2]+12Mod[#,2]&[Mod[Quotient[UnixTime[]-2700,900]/2,24]]]

Original Code is

a = Mod[Quotient[UnixTime[] - 3 * 900, 900] / 2, 24];
result = FromCharacterCode[128336 + Quotient[a, 2] + Mod[a, 2] * 12];
Print[result]
\$\endgroup\$

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.