16
\$\begingroup\$

In this challenge you will need to determine whether it's Pi Day, Pi Minute, or Pi Second.

Because Pi is irrational, it wants your code to be as short as possible.

Examples

No input is provided, your program should use the system time. I've just added it for clarity

March 14, 2016 0:00:00
Pi Day
December 25, 2015 3:14:45
Pi Minute
December 29, 2015 0:03:14
Pi Second
January 1, 2016 0:00:00
<No Output>

What is Pi Day / Minute / Second

  • Pi Day is when the month is March, and the date is the 14th
  • Pi Minute is when the hour is 3, and the minute is 14
  • Pi Second is when the minute is 3, and the second is 14
  • Pi Day should be preferred instead of Pi Minute or Pi Second, and Pi Minute should be preferred instead of Pi Second.
  • For this challenge you should use 12-hour time (15:14 == 3:14). The date/time used to determine the Pi Day/Minute/Second should be based on system time.

Scoring & Bonus

-15 byte Bonus: If you print "No Pi Time" when it's not Pi time.


As always, standard loopholes are disallowed. This is shortest code in bytes wins!

\$\endgroup\$
  • 6
    \$\begingroup\$ I don't think Costco allows you to purchase the mathematical constant pi at any time of the year. \$\endgroup\$ – Alex A. Jan 2 '16 at 1:35
  • 2
    \$\begingroup\$ You've changed it to regular pie. That's also false because you can get pie from Costco all year. \$\endgroup\$ – Alex A. Jan 2 '16 at 1:39
  • 1
    \$\begingroup\$ @AlexA. Hmm, weird I can never find it in the summer... \$\endgroup\$ – Downgoat Jan 2 '16 at 1:40
  • 1
    \$\begingroup\$ Because pi is infinitely long and you want to be passive-aggressive? \$\endgroup\$ – Arcturus Jan 2 '16 at 1:53
  • 8
    \$\begingroup\$ I went to Costco today - they were closed. \$\endgroup\$ – Digital Trauma Jan 2 '16 at 5:18

11 Answers 11

4
\$\begingroup\$

CJam, 41 bytes

et[3E]#"
Pi Day

Pi Minute
Pi Second
"N/=

Test it here. Alternatively use this link to stub the result of et for easier testing.

Explanation

et   e# Get the current datetime as an array with the following elements:
     e#   - Year
     e#   - Month
     e#   - Day
     e#   - Hour
     e#   - Minute
     e#   - Second
     e#   - Millisecond
     e#   - Weekday
     e#   - Tickrate or something.
[3E] e# Push the array [3 14].
#    e# Find the position of this subarray in the current datetime array. Let's see
     e# what results we can get:
     e#   - Year 3 is in the past and there is no 14th month, so we can't get 0.
     e#   - Pi day will give result 1.
     e#   - Day 3, hour 14 would give 2.
     e#   - Pi minute will give result 3.
     e#   - Pi second will give result 4.
     e#   - Second 3, millisecond 14 would give 5.
     e#   - Weekday and tickrate won't be 14, so we'll never get 6 or 7.
     e#   - If [3 14] isn't found at all we get -1.
"\Pi Day\\Pi Minute\Pi Second\"
     e# Push this string (with linefeeds instead of backslashes.
N/   e# Split into lines.
=    e# Select the corresponding element. The non-existent "pi hour" and "pi millisecond"
     e# would map to empty strings as well as the -1.
\$\endgroup\$
8
\$\begingroup\$

Javascript (ES6), 114 112 - 15 = 97 bytes

x=>['Pi Day','Pi Minute','Pi Second'].find((x,i)=>[/ar 14/,/(03|15):14:/,/03:14/][i].test(Date()))||'No Pi Time'

Ungolfed:

x=>
['Pi Day', 'Pi Minute', 'Pi Second']  // array of outputs
.find(                                // find first element in the array
    (x, i)=>                          // which returns truthy for this function
    [/ar 14/, /(03|15):14:/, /03:14/] // array of regex patterns
    [i]                               // get corresponding regex based on index
    .test(Date())                     // test it against current date, date is automatically cast to string
) || 'No Pi Time'                     // if no result, then return "No Pi Time"

Thanks for -2 bytes @edc65

\$\endgroup\$
  • \$\begingroup\$ Could be Date() instead of new Date \$\endgroup\$ – edc65 Jan 2 '16 at 10:56
  • \$\begingroup\$ 'Pi '+['Day','Minute','Second'].find((x,i)=>................ \$\endgroup\$ – wizzwizz4 Jan 3 '16 at 9:13
  • \$\begingroup\$ @wizzwizz4 this won't work. If it's not Pi time, it returns "Pi undefined" \$\endgroup\$ – nderscore Jan 3 '16 at 17:04
  • \$\begingroup\$ Would a check for undefined be shorter than 6 chars? \$\endgroup\$ – wizzwizz4 Jan 3 '16 at 17:39
  • 1
    \$\begingroup\$ @nderscore It's fewer bytes to say nderscore than underscore. \$\endgroup\$ – wizzwizz4 Jan 3 '16 at 18:26
5
\$\begingroup\$

Ruby, 125 124 chars

i=[*[(t=Time.new).month,t.day,t.hour,t.min,t.sec].each_cons(2)].index [3,14];i&&$><<['Pi Day','','Pi Minute','Pi Second'][i]

Alas, the cleverer %i[month day hour min sec].map{|x|Time.new.send x} is longer.

The key here is the use of each_cons to avoid repetition (see the last few lines of the explanation below).

i=                          # send i (index) to...
[*                          # convert to array (splat)...
 [
  (t=Time.new).month,       # the current month...
  t.day,t.hour,t.min,t.sec  # etc... (duh)
 ]
 .each_cons(2)              # each consecutive two elements
]                           # [[month, day], [day, hour], [hour, min], etc]
.index [3,14];              # first occurrence of [3, 14]
i&&                         # shorthand for "if i"...
$><<                        # output...
[
 'Pi Day',                  # [month=3, day=14] is Pi Day
 '',                        # [day=3, hour=14] isn't anything
 'Pi Minute',               # [hour=3, min=14] is Pi Minute
 'Pi Second'                # [min=3, sec=14] is Pi Second
][i]                        # index by index (obviously)
\$\endgroup\$
  • \$\begingroup\$ You could save a few chars by pulling out 'Pi' like you did with t, no? \$\endgroup\$ – Cole Johnson Jan 2 '16 at 6:07
  • \$\begingroup\$ @Cole And what will you do with the second element? \$\endgroup\$ – nicael Jan 2 '16 at 14:21
  • \$\begingroup\$ Why isn't Pi Hour anything. What's wrong with 2 in the afternoon, tomorrow? \$\endgroup\$ – Mr Lister Jan 2 '16 at 14:31
  • \$\begingroup\$ @ColeJohnson No, [(p='Pi ')+Day','',p+'Minute',p+'Second'] is longer. \$\endgroup\$ – Doorknob Jan 2 '16 at 16:17
4
\$\begingroup\$

Python 2, 219 186 183 Bytes (198-15)

I tried

Ungolfed:

from datetime import datetime

now = datetime.now()
output = ['Pi Day', 'Pi Minute', 'Pi Second', 'No Pi Time']

if now.month == 3 and now.day == 14:
    print output[0]
elif now.hour == 2 and now.minute == 13:
    print output[1]
elif now.minute = 2 and now.second == 13:
    print output[2]
else:
    print output[3]

Golfed:

from datetime import *
n=datetime.now()
a=n.minute
if n.month==3and n.day==14:print'Pi Day'
elif n.hour==2and a==13:print'Pi Minute'
elif a==2and n.second==13:print'Pi Second'
else:print'No Pi Time'
\$\endgroup\$
  • 4
    \$\begingroup\$ from datetime import*;n=datetime.now() is shorter. Also, there's no point in indexing into an array when you're printing constant strings. \$\endgroup\$ – Doorknob Jan 2 '16 at 1:29
  • \$\begingroup\$ @Doorknob冰 That's true :) \$\endgroup\$ – Zizouz212 Jan 2 '16 at 1:36
  • \$\begingroup\$ Shorter even: paste.ee/p/ebcSh \$\endgroup\$ – Rɪᴋᴇʀ Jan 2 '16 at 1:40
  • \$\begingroup\$ Made by swapping if/elses with [else,if][statement]. \$\endgroup\$ – Rɪᴋᴇʀ Jan 2 '16 at 1:41
  • 1
    \$\begingroup\$ The latter numbers are wrong (2:13 instead of 3:14), and the 12-hour clock requirement isn't met. (Seems to apply to some other answers too) You can also get it shorter by indexing the result of time.localtime(); it comes down to 148-15 bytes (without the 12-hour fix). The 12-hour thing is unfortunate though; without it you could easily get it down to 129-15 bytes: import time;x=3,14;T=time.localtime();print{1:'Pi Day',3:'Pi Minute',4:'Pi Second'}.get((zip(T,T[1:])+[x]).index(x),'No Pi Time') (and 118-15 bytes on Python 3, by converting to bytes and using find, which makes things simpler) \$\endgroup\$ – Aleksi Torhamo Jan 2 '16 at 3:49
4
\$\begingroup\$

Japt, 78 - 15 = 63 bytes

D=Ð)g ¥3©Df ¥E?"Pi Day":Dd %C¥3©Dc ¥E?`Pi M©e`:Dc ¥3©Db ¥E?`Pi SeÖ:No Pi Te

Pretty straightforward - just checks the date for every case.

Explanation:

  • D=Ð)g get the current date (Ð), store it in the variable D and get the month (g). Why store it in the variable, if it's already one-letter? Because since then you can dress any part of date with Da, where a is the function, returning year, month, date, etc. But otherwise you'd have to do Ð a, see the space.

  • ¥3 is ==3, checking if the month is March.

  • © is &&, i.e. "and".
  • Df is the day of the month.
  • E is 14
  • ?...:... - typical sets of ternary operators
  • Dd %C the reminder of dividing the hour (Dd) by 12 (C)
  • Dc is the minutes
  • Db are seconds

Try it online!


To emulate Pi Day:

D=Ð"3/14/11 11:11:11";
Dg ¥2©Df ¥E?"Pi Day":Dd %C¥3©Dc ¥E?`Pi M©e`:Dc ¥3©Db ¥E?`Pi SeÖ:No Pi Te

To emulate Pi Minute:

D=Ð"11/11/11 3:14:11";
Dg ¥2©Df ¥E?"Pi Day":Dd %C¥3©Dc ¥E?`Pi M©e`:Dc ¥3©Db ¥E?`Pi SeÖ:No Pi Te

To emulate Pi Second:

D=Ð"11/11/11 00:3:14";
Dg ¥2©Df ¥E?"Pi Day":Dd %C¥3©Dc ¥E?`Pi M©e`:Dc ¥3©Db ¥E?`Pi SeÖ:No Pi Te
\$\endgroup\$
3
\$\begingroup\$

TI-BASIC, 124 bytes

Thanks to FlagAsSpam for shaving a few bytes.

"→Str1
getTime
If min({3,14}={Ans(2),Ans(3
"Pi Second→Str1
getTime
If Ans(2)=14 and max(Ans(1)={3,14
"Pi Minute→Str1
getDate
If min({3,14}={Ans(2),Ans(3)
"Pi Day→Str1
Str1
\$\endgroup\$
  • \$\begingroup\$ Are you using i (imaginary unit) and e (Euler's constant) as shortcuts? If not, that could also save you some bytes. \$\endgroup\$ – Addison Crump Jan 2 '16 at 19:30
  • \$\begingroup\$ @FlagAsSpam I thought about using those, but I wasn't sure if it counts. \$\endgroup\$ – Conor O'Brien Jan 2 '16 at 19:39
  • \$\begingroup\$ @FlagAsSpam Whether or not they're valid here, e is actually two bytes! \$\endgroup\$ – lirtosiast Jan 2 '16 at 21:37
  • \$\begingroup\$ @ThomasKwa Oh, right. \$\endgroup\$ – Conor O'Brien Jan 2 '16 at 21:39
  • \$\begingroup\$ @FlagAsSpam It is no longer invalid. ^_^ \$\endgroup\$ – Conor O'Brien Jan 2 '16 at 23:26
3
\$\begingroup\$

Perl, 80 - 15 = 65 bytes

print'No 'x localtime!~/(ar | 15:|03:)14/,'Pi ',(Time,Day,Minute,Second)["@-"/4]

Take 2, parsing the string representation of localtime. At present, this looks something like this:

Sun Jan  3 15:14:15 2016

The position of the matched string is used to determine the correct Pi Time.


Perl, 100 bytes

@t=localtime;$t[2]%=12;3-/3/^{@t[$_,$_+1]}->{14}||exit!print'Pi ',(Second,Minute,_,Day)[$_]for 3,1,0

localtime returns the months zero indexed, hence the need for 3-/3/.

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

Python 3, 137 - 15 = 122 bytes

import time
T=list(time.localtime())
T[3]%=12
print({1:'Pi Day',3:'Pi Minute',4:'Pi Second'}.get(bytes(T[1:6]).find(b'\x03\x0e'),'No Pi Time'))

The 12-hour requirement was unfortunate, as this would've been 118-15=103 bytes without it:

import time
print({1:'Pi Day',3:'Pi Minute',4:'Pi Second'}.get(bytes(time.localtime()[1:6]).find(b'\x03\x0e'),'No Pi Time'))
\$\endgroup\$
2
\$\begingroup\$

AppleScript, 202 190 187 183 181 bytes

Hey, this isn't so bad after all.

set n to current date
set b to n's time string
if n's date string contains"March 14"
log"Pi Day"
else if b contains"3:14:"
log"Pi Minute"
else if b contains"3:14"
log"Pi Second"
end

I actually found a use for AppleScript's method calling. Go figure. Nope. Just turns out that I'm an idiot. Setting a variable is shorter.

(for those wondering, current date command returns a date-type with the contents "Saturday, January 2, 2016 at 2:46:01 PM" or the like)

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

PHP, 85 - 15 = 70 bytes

<?=['No Pi Time','Pi Day','Pi Minute','Pi Second'][strpos(@date(Ymdhi_is),'0314')/4];

The main trick use here is the Ymdhi_is date format, at the time of writing, date('Ymdhi_is') returns 201501030258_5828.

  • md, hi and is are the values who will be replaced by 0314 if it's Pi-something. Note that all those strings will be always be replaced by a 4-character long string.
  • They are put in that specific order since strpos will stop searching at the first occurrence of the needle, so we put them in the order of priority.
  • A separator between hi and is is necessary because we don't want strpos to match a value that would overlap both (thanks to primo for saving bytes here).
  • The needle is 0314 because 314 would wrongly match 10:31:42 as Pi-Second.

The Y part is the trickiest. We need a prefix to to offset the first occurrence of Pi-something, allowing us to distinguish strpos's return values between false (not found, Pi-nothing) and 0 (found at index 0, Pi-day).

And we want this prefix to be either 4 or 5-character long, since we are planning to divide strpos's return value by 4.

Y is 4-character long, but:

  • it will be 5-character long someday, and this will break the program (think about year 10314): the PHP documentation says that Y will be replaced by 4 digits, but it's not true.
  • if you come back in time, at year 314, it will break the program.

Since PHP didn't exist in year 314, and will likely not exist anymore in year 10314, I guess these bugs can be safely ignored.

Note that 0314 can overlap Ymd since:

  • Ymmd configuration: there's no 31st month.
  • YYmm configuration: there's no 14th month.
  • YYYm configuration: there are less than 40 months.

Also, there's a version without the bugs related to the year, which is 86 - 15 = 71 bytes:

<?=['No Pi Time','Pi Day','Pi Minute','Pi Second'][strpos(@date(D_mdhi_is),'0314')/4];
\$\endgroup\$
  • \$\begingroup\$ Great answer. If you use underscores rather than dots, you can drop the quotes around Ymd_hi_is. Also, I don't think a separator is necessary between md and hi, as the 12-hour h can never be 14, and never start with 3 or 4. \$\endgroup\$ – primo Jan 3 '16 at 7:02
0
\$\begingroup\$

Python 3, 179 bytes

import functools as F,datetime as D
T,G=D.datetime.now(),getattr
F.reduce(lambda i,j:print("Pi "+i.title())if G(T,i)/G(T,j)==3/14else j,"month day hour minute second".split(" "))
\$\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.