Take the 2-minute tour ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

Happy birthday to Me!

Write a program that prints Happy birthday to me! on its birthday.

  1. The program's birthday is the creation, last modification or compilation time of the program (you choose), and must not be hard-coded.
  2. The date you use as the birthday must not be affected by the program's invocation or execution in any way. You can't modify your birthday.
  3. For extra credit (-15% byte count), print Happy birthday to you! on your birthday (hard coded), if it doesn't coincide with the program's. Or use some celebrity's birthday and get -14%.
  4. It must print only this, and not print anything on any other day.
  5. Count bytes, in UTF-8.
  6. Use the Gregorian calendar.

Good luck and happy birthday (to the newborn programs).

P.S.
Following Izkata's comment, if you print Happy birthday to Mel on Mel Kaye's birthday, you get 20% off. But you have to provide a credible source that it's this date.

share|improve this question
1  
@TeunPronk, You can't do both. Either use your own birthday, or a celebrity's (or none, and give up the extra credit). –  ugoren Feb 18 at 16:07
4  
@TeunPronk: Only Jon Skeet can :P –  MSalters Feb 18 at 18:09
11  
I saw this in the Hot Questions sidebar and read "Happy Birthday to Mel"... –  Izkata Feb 18 at 19:23
1  
@Izkata, Updated the question in honor of Mel. –  ugoren Feb 19 at 11:37
1  
@Victor, whatever answer he'd post, I'll automatically accept. –  ugoren Feb 19 at 15:33

22 Answers 22

up vote 10 down vote accepted

PHP 77 75 74 65 60

Many thanks to the superb suggestions from Tim Seguine:

<?date(dm,getlastmod())-date(dm)&&die?>Happy birthday to me!

Sneaky PHP: 46 42 41 40

Using Phil H's idea and again Tim Seguine's suggestion:

<?touch(__FILE__)?>Happy birthday to me!
share|improve this answer
    
Doesn't it include the year in the comparison? if so, it only works on the 0th birthday. –  ugoren Feb 18 at 17:54
    
@ugoren You're right! Thanks for the correction. 2 bytes saved. –  ComFreek Feb 18 at 17:58
    
If "doesn't preint anything" in the rules is construed to mean standard output, then you could win 4 bytes by removing the '' around the dm strings. It generated a warning, but I believe it gets sent to standard error if error reporting is on. –  Tim Seguine Feb 18 at 21:52
4  
<?date(dm,stat(__FILE__)[9])-date(dm)&&die?>Happy birthday to me! –  Tim Seguine Feb 18 at 22:30
1  
@TimSeguine Thanks for your suggestions! I've incorporated them into my answer, I hope you don't mind. –  ComFreek Feb 19 at 13:35

Bash (sneaky): 36

touch $0;echo Happy Birthday to me\!

According to the rules: "creation, modification or compilation time of the program". I choose modification time, and a perpetual self-modification. [HT @ace for 1 char]

Perl (also sneaky): 29

print "Happy birthday to me!"

This one is arguably less sneaky than the first; Perl programs are always compiled before they are executed, which not everyone knows - see, there is an educational spin on the sneakiness. So here it is the compilation date that I'm using.

-- Edit for rule change --

This was written before there was any rule about changing your birthday. I think the Perl one still stands; all Perl programs are compiled before they are run. I'll leave the answer here for educational reasons!

share|improve this answer
5  
Ok, cheater, get my +1 for the cleverness. –  Victor Feb 18 at 16:49
1  
You can escape the ! with \! and remove the quotes to save 1 char –  ace Feb 18 at 16:56
1  
Nice trick, but the rules explicitly forbid it (now). –  ugoren Feb 18 at 17:53
1  
@ugoren Still doesn't forbid the perl solution, which is compiled before the program starts. –  Cruncher Feb 18 at 19:06
3  
@Cruncher, I'm afraid you're right. I'll consult my lawyer and send you the bill. –  ugoren Feb 18 at 19:17

bash - 65

[ `date +%d%m -r $0` = `date +%d%m` ]&&echo Happy birthday to me!

Thanks to ugoren, ace and nyuszika7h for help.

share|improve this answer
    
I think you can escape the ! with \! so you don't need the quotes and save 1 char. –  ace Feb 18 at 16:54
    
Actually I had the quotes since I thought echo would require them for the spaces. I took them out and did not escape the exclamation mark and it still worked. Thanks for the tip! –  shiona Feb 18 at 16:59
2  
You only need to escape ! in interactive shells, not scripts. –  nyuszika7h Feb 18 at 18:59
    
You can save two characters by using [ and ] instead of [[ and ]]. –  nyuszika7h Feb 18 at 18:59
    
Does it work when the year isn't the same as the creation date? –  ugoren Feb 18 at 19:19

C# 198.05 (233 - 15%)

using s=System;class P{static void Main(){string t=s.DateTime.Now.ToString("Mdd"),b="1202";if(s.IO.File.GetCreationTime(typeof(P).Assembly.Location).ToString("Mdd")==t|b==t)s.Console.Write("Happy birthday to "+(b==t?"you!":"me!"));}}

Formatted:

using s = System;
class P
{
    static void Main()
    {
        string t = s.DateTime.Now.ToString("Mdd"), b = "1202";
        if (s.IO.File.GetCreationTime(typeof(P).Assembly.Location).ToString("Mdd") == t | b == t)
            s.Console.Write("Happy birthday to " + (b == t ? "you!" : "me!"));
    }
}

191 (No bonus)

using s=System;class P{static void Main(){if(s.IO.File.GetCreationTime(typeof(P).Assembly.Location).ToString("Mdd")==s.DateTime.Now.ToString("Mdd"))s.Console.Write("Happy birthday to me!");}}

181,05 (213 - 15%)

With some additional instructions (you need to compile this to b.exe and run it from the directory the executable is in) I can get it down to this:

using s=System;class P{static void Main(){string t=s.DateTime.Now.ToString("Mdd"),b="1202";if(s.IO.File.GetCreationTime("b.exe").ToString("Mdd")==t|b==t)s.Console.Write("Happy birthday to "+(b==t?"you!":"me!"));}}

171 (No bonus)

Same instructions as above, this time only printing a message on it's own birthday (so no -15% bonus).

using s=System;class P{static void Main(){if(s.IO.File.GetCreationTime("b.exe").ToString("Mdd")==s.DateTime.Now.ToString("Mdd"))s.Console.Write("Happy birthday to me!");}}
share|improve this answer
    
You could save few bytes in the bonus ones by adding ,b="1202"==t after you get the date string and using that instead. –  ahruss Feb 18 at 17:42
1  
Thanks! Though "few bytes" turns out to be one... or am I missing something? Edit Ah, I see; you said ,b="1202"==t but the ==t part is not possible since that evaluates to a bool and the other var is a string. You cannot (AFAIK that is) use two different types in one "var" declaration. –  RobIII Feb 18 at 17:57
    
Ah, okay. It's been a while since I've used C#. My bad. –  ahruss Feb 18 at 18:03
    
You could shorten the simpler version by comparing dates, not strings. This mens using something like CreationTime.Date == DateTime.Today. –  svick Feb 18 at 19:10
    
That would only work for today/this year/birthday 0. How would that work for other years? –  RobIII Feb 18 at 19:38

Java - 275 - 15% = 233.75 with bonus / 237 without bonus

With bonus:

import java.util.*;class L{public static void main(String[]y){int s=f(new Date());String j="Happy birthday to ";System.out.print(s==f(new Date(new java.io.File("L.class").lastModified()))?j+"me!":s==183?j+"you!":"");}static int f(Date d){return d.getMonth()*40+d.getDate();}}

Without the bonus:

import java.util.*;class L{public static void main(String[]y){if(f(new Date())==f(new Date(new java.io.File("L.class").lastModified())))System.out.print("Happy birthday to me!");}static int f(Date d){return d.getMonth()*40+d.getDate();}}

I was born in April, 23rd.

share|improve this answer
1  
Happy birthday to, not for ;-) Just saved you another byte :-) –  RobIII Feb 18 at 16:26
    
@RobIII Thanks, fixed. –  Victor Feb 18 at 16:27
    
Also, the newline (\n) is not required AFAIK which saves you another 4 bytes ;-) –  RobIII Feb 18 at 16:28
    
@RobIII Thanks again. –  Victor Feb 18 at 16:29
    
Yeah... I should stop shooting my own foot :P You're welcome ;) –  RobIII Feb 18 at 16:31

I'm pretty proud of this little trick to save a few bytes on the message. I hope it will be included in other answers. I was the first to think of this!

Python

105 characters, no extra credit. Save the file as "happy birthday to me" and run. Runs in GMT only, and "birthday" is defined as the date of your birth, not it's anniversary (also often call "birthday").

import sys,os,time
if (int(os.stat(*sys.argv).st_atime/86400)==int(time.time()/86400)):print sys.argv[0]

For it to work, save this as "happy birthday to me" and run python "happy birthday to me"

Note: of course, the all but a small bootstrap could be in the filename, making any arbitrarily large code reduce down to the bootstrap. Normally I would consider this "cheating". However, "happy birthday to me" is not an unreasonable filename - it describes what the program does, much better than some programs (e.g. "python"), so in this case I'm going to allow it :)

share|improve this answer
    
I think relying on the file name is cheating (though I didn't forbid it explicitly). If it's allowed, why not just write eval(sys.argv[0])? –  ugoren Feb 19 at 7:56
    
And I didn't bother to define a birthday, but it's a day that comes once a year when a person celebrates the anniversary of their birth, not the exact day when you were born. –  ugoren Feb 19 at 7:58
    
ugoren: I did mention that in my note at the bottom (which pre-dates your comment). However, "happy birthday to me" is not an unreasonable filename - it describes what the program does, much better than some programs (e.g. "python"), so in this case I'm going to allow it –  AMADANON Inc. Feb 19 at 18:52

Matlab: 66

t=dir('f.m');if strncmp(t.date,date,5),'Happy birthday to me!',end

File name has to be 'f.m'

share|improve this answer
1  
On your birthday it should say "Happy birthday to you!" :-) –  RobIII Feb 18 at 17:20
    
@RobIII:Oops, you'r right, I didn't read carefully enough. Will remove the second version. Thanks! –  H.Muster Feb 18 at 17:22
    
I assume strncmp(x, y, 5) compares dates like 28-12-2013's first 15 characters (being 28-12 e.g. dec. 28th). Does this also work when the user's locale settings are yyyy/mm/dd for example? Does Matlab default to dd-mm-yyyy always? (Just curious). Edit Nevermind: found it!. It seems it does. It wouldn't matter anyway for mm/dd/yyyy or dd-mm-yyyy since both left and right operand would use the same format anyway and both 5 leftmost chars would match anyway; as long as the year is never leading. –  RobIII Feb 18 at 21:11
    
Why do you need the variable t? Doesn't dir('f.m').date work? –  ugoren Feb 19 at 13:15
    
@ugoren: t is necessary to make dir return the file attributes (otherwise it would it would just return all files in the directory that match 'f.m'). Furthermore, t is necessary to access the date field. –  H.Muster Feb 19 at 15:52

GNU COBOL with -free, 204

PROGRAM-ID.B.DATA DIVISION.WORKING-STORAGE SECTION.
1 A PIC XXXX/XX.
1 B PIC X(5).
1 C PIC X(21).
PROCEDURE DIVISION.ACCEPT A FROM DATE
ACCEPT C
MOVE WHEN-COMPILED TO B
IF A(3:5) = B OR "12/09" DISPLAY C.

I break the rules about the celebrity, so no bonus there...

The text produced is user-input (requested when run). If that is not good-to-go, then the line defining C needs to be deleted, as does ACCEPT C, and DISPLAY C must become DISPLAY "HAPPY BIRTHDAY TO ME!", for an extra seven characters.

WHEN-COMPILED is a special-register containing compile date/time which is available to the program (always handy, you can know you have the correct version). It is truncated in the MOVE because the rest isn't needed. DATE is the current date - this one is yymmdd.

The / in the definition of A is an insertion editing symbol, since the compile-date contains slashes. An extra character, but eases the compare.

Celebrity = Grace Hopper

share|improve this answer

Ruby - 80 103 87 bytes

m=File.mtime $0
t=Time.now
puts"Happy birthday to me!"if t.month==m.month&&t.day==m.day

Ruby - 123 115 135 121 - 15% = 104.55 97.75 114.75 102.85 points

t=Time.now
{me:File.mtime($0),you:Time.at(36e5)}.map{|n,d|puts"Happy birthday to #{n}!"if t.month==d.month&&t.day==d.day}

Might be a little longer or shorter depending on where your birthday falls in the year, and the shortest way to represent that. For mine, that's 36e5 (seconds since epoch; time zone dependent).


Does Mel Gibson count? Here's a 138 byte - 35% bonus = 89.7-point program that celebrates itself, me, and Mel!

t=Time.now
{me:File.mtime($0),you:Time.at(36e5),Mel:Time.at(2e5)}.map{|n,d|puts"Happy birthday to #{n}!"if t.month==d.month&&t.day==d.day}
share|improve this answer
    
Your code fails on leap years, for dates after February. –  ugoren Feb 19 at 17:57
    
@ugoren right you are. Fixed that, but lost a lot of points :( –  Tim S. Feb 19 at 18:22
    
But now I've reclaimed most of those! =) –  Tim S. Feb 19 at 19:05

Batch - 37 Bytes

Stealing the method used by one of the Bash answers..

@echo.>>%0&echo Happy birthday to me!

Other method - 145 Bytes

@for /f "tokens=2,3 delims=/ " %%a in ("%date%")do @for /f "tokens=1,2 delims=/" %%c in ("%~t0")do @if %%a%%b==%%c%%d @echo Happy Birthday to me!
share|improve this answer

Ruby, 69 characters/bytes

puts'Happy birthday to me!'if(Time.new-File.atime($0))%31536000<86400

31536000 is the number of seconds in a year, and 86400 is the number of seconds in a day.

share|improve this answer
4  
Unfortunately, only works correctly for maximum of seven years or so, until you run into the first leap year after the atime. –  Amadan Feb 19 at 2:47
    
Also says "happy birthday" on the morning after your birthday, and doesn't say happy birthday the morning of your birthday before your birth time. –  AMADANON Inc. Feb 19 at 3:23

JavaScript

Node.js, 156 bytes

b=new Date(require("fs").statSync(__filename).mtime);d=new Date();b.getDate()==d.getDate()&&b.getMonth()==d.getMonth()&&console.log("Happy birthday to me!")

Uses the file's modification time.

share|improve this answer
    
beating you by 56 bytes so far =P –  stroncium Feb 20 at 10:50
    
I get a runtime error when I run yours, but the match approach is definitely much cleverer. Fix the error and you've got my upvote. ;) –  Chris W. Feb 20 at 18:15
    
Can you quote the error and your OS? I guess it's just not crossplatform. –  stroncium Feb 26 at 13:10

PureBasic

Without Bonus - 142

If Bool(FormatDate("%dd%mm",Date())=FormatDate("%dd%mm",GetFileDate(ProgramFilename(),0)))
MessageRequester("","Happy birthday To me!")
EndIf

With Bonus - 218 - 15% = 185.3

Dim s$(2)
s$(1)="me"
s$(2)="you"
m$="%dd%mm"
d$=FormatDate(m$,Date())
i=Bool(d$=FormatDate(m$,GetFileDate(ProgramFilename(),0)))|(Bool(d$="2301")<<1)
If i=0:End:EndIf
MessageRequester("","Happy birthday To "+s$(i)+"!")
share|improve this answer

TI-BASIC, 68 bytes

If Ans=0:getDate→G:0:G=G:If getDate=G:Disp "HAPPY BIRTHDAY TO ME!"

Remember, these tokens are one byte: If , Ans, →, Disp. getDate is two bytes. All other one-character symbols are one byte.

share|improve this answer
1  
Are you sure that's UTF-8? –  Fozzedout Feb 18 at 16:53
3  
OP explicitly states you should use UTF-8. That's 66 characters and 68 bytes. –  nyuszika7h Feb 18 at 19:02
2  
If you want to claim it's 46 bytes, write it in 46 bytes. As it is now, it's 68 bytes. –  ugoren Feb 18 at 19:33
    
According to the token sizes in a standard TI-Basic environment it is 55 bytes, but as plain text yea its 68. Also technically there does not have to be a " at the end so that could save a byte. –  lemondrop Feb 19 at 6:56

J 79

 echo((6!:0'')(('',:'Happy birthday to me!'){~])@:-:&(1 2&{)&:>])1{,1!:0{:4!:3''

Bonus version120 - 15% = 102

Do I get extra credit for also printing both when both are having their birthday?

echo((2 6$(6!:0 '') , 0 2 7)(' ','Happy birthday to ',"2 1]3 5$'you! me!  both!'){~#.@:(-:&(1 2&{)"1)&:>])1{,1!:0{:4!:3''

Explanation (right to left):

last =: {:4!:3''     NB. Take the last script run (i.e. the file itself)
time =: 1{,1!:0 last NB. the modification time is the second element in that file's listing

The central verb of the train

unbox_both =: &:>      NB. unboxes left and right argument
match  =: -:&(1 2&{)"1 NB. for each date given, left and right, compare them
to_int =: #.           NB. convert boolean to int
from   =: {~           NB. from the left array, take element right.

NB. H contains messages an empty row, appended to all combinations of messages. 
H =: (' ','Happy birthday to ',"2 1]3 5$'you! me!  both!')

V =: (H from to_int)@:match unbox_both NB. after unboxing and comparing, 
                                       NB. select the according message

The left tine for the central train:

dates=: (2 6$(6!:0 '') , 0 2 7) NB. the current date, and the relevant fields of my birthday.

NB. Combining the bricks:
echo (dates V ]) time           NB. output the monads result on time.
share|improve this answer

Powershell - 105 bytes

if('{0:M}'-f(gi $MyInvocation.MyCommand.Definition).creationtime-eq(date -f M)){'Happy birthday to me!'}

Ungolfed:

if('{0:M}' -f (gi $MyInvocation.MyCommand.Definition).creationtime -eq (date -f M)){
  'Happy birthday to me!'
}

The bonus isn't worth it, I can only get 117.5.

share|improve this answer

Powershell - 127

if ((gci $MyInvocation.MyCommand.Path).lastwritetime.ToString("MMdd") -eq (get-date).ToString("MMdd")){"happy birthday to me!"}

For the 15% bonus - 151 bytes, less 15% = 128.4

$r=@{"0308"="you";(gci $MyInvocation.MyCommand.Path).lastwritetime.ToString("MMdd")="me"}[(get-date).tostring("MMdd")]
if($r){"Happy birthday to $r!"}
share|improve this answer
1  
I'm no powershell expert, but this will only work in the current year? What what when the "program" has it's 1st, 2nd, 3rd etc. birthday? –  RobIII Feb 18 at 21:09
    
You can remove the write command - With just "happy birthday to me!" it will print it out. –  unclemeat Feb 18 at 23:08
    
Your quite right. I should know that. –  Chris J Feb 18 at 23:22
    
@Robill - oops. That's what comes of writing something when I'm distracted by something else and using codegolf as procrastination. Fixed (not that it's got a chance of winning, mind). –  Chris J Feb 19 at 8:55

Java - 196

This differs from the other Java submission by using Strings, shaving 41 characters off in the process. It uses String.format("%tj") to format a java.util.Date or a long as a day-of-year String, and then compares these two Strings.

class Z{public static void main(String[]y){if("".format("%tj",new java.util.Date()).equals("".format("%tj",new java.io.File("Z.class").lastModified())))System.out.print("Happy birthday to me!");}}

Formatted:

class Z
{
    public static void main(String[] y)
    {
        if ("".format("%tj", new java.util.Date()).equals("".format("%tj", new java.io.File("Z.class").lastModified())))
            System.out.print("Happy birthday to me!");
    }
}
share|improve this answer
1  
Day of year doesn't work well with leap years. –  ugoren Feb 20 at 5:39
    
@ugoren I agree. However, since the contest is currently running and we're at Feb. 20th. the compilation dat should be fine for a few days and not cause a problem following years. When compiling after Feb. 28th there will be a (future) problem indeed. –  RobIII Feb 20 at 8:47
    
If I were compiling after February 28th I could change the String format to "%tm%td" at a six point character cost –  timxyz Feb 20 at 10:31

C# 191 no bonus

using s=System;class P{static void Main(){if(s.IO.File.GetCreationTime(typeof(P).Assembly.Location).ToString("Mdd")==s.DateTime.Now.ToString("Mdd"))s.Console.Write("Happy birthday to me!");}}

formatted:

using s = System;
class P
{
    static void Main()
    {
        if (s.IO.File.GetCreationTime(typeof(P).Assembly.Location).ToString("Mdd") == s.DateTime.Now.ToString("Mdd"))
            s.Console.Write("Happy birthday to me!");
    }
}
share|improve this answer
    
You use x only twice; var x="MMdd"; + ToString(x) + ToString(x) = 15 whereas ToString("MMdd"); + ToString("MMdd"); only costs 12. –  RobIII Feb 19 at 21:02
    
Also, a newline is not required so WriteLine() can be shortened to Write(). With above and this change in place you have the exact same solution as I do ;-) –  RobIII Feb 19 at 21:15
    
Thank you, I updated the code :) –  Alberto Feb 20 at 8:32
1  
You should update the score too, which is 193 now. And you can get it down to 191 by shaving two M's off * hint * :P –  RobIII Feb 20 at 8:41

JavaScript (node.js) - 100 bytes

(require('fs').fstatSync(4).mtime+1).match(Date().substr(4,6))&&console.log('Happy birthday to me!')
share|improve this answer

vb.net ~161c

This will print the celebration message to all whose birthday it is.

Module M
Sub Main
For Each b In{({"1705","Alan"}),({"2012","You"}),({FileDateTime(Process.GetCurrentProcess.MainModule.FileName).ToString("ddMM"),"Me"})}
If b(0)=Now.ToString("ddMM") Then Console.WriteLine("Happy Birthday To {0}!",b(1))
Next
End Sub
End Module

Alan => Alan Kaye

Score: 253c (-33c vb.net min) = 220 - 15% (my birthday bonus) = 187c - 14% (Celeb Birthday) = 160.82 ~161c or 220c - 29% = 156.2 ~157c

share|improve this answer
    
You can get a bonus for your birthday OR a celebrity. Not both. –  ugoren Mar 30 at 6:27
    
@ugoren Scoring doesn't state it's an exclusive or, so I'm using the logical meaning of or. –  Adam Speight Mar 30 at 21:14

C# - 63 bytes

class P
{
    static void Main()
    {
          Console.Write("Happy birthday to me!"));
    }
}

I choose compilation time. Since the C# code compiles to MSIL which on runtime is compiled to the executable code by the JIT Compiler, this program meets the conditions.

EDIT-- Possibly invalid answer as pointed in comments.

share|improve this answer
1  
Old trick, no longer valid. Rule 2 says "must not be affected by the program's invocation or execution in any way". –  ugoren Feb 19 at 11:30
    
updated accordingly. Thank You @ugoren –  rahulroy9202 Feb 19 at 11:42
    
@ugoren The PERL code by Phil H also uses this very same trick. Check the highest voted answer. –  rahulroy9202 Feb 19 at 11:46
2  
It's also an invalid answer. But - he was first to use this trick, and at the time he did it the rules allowed it. –  ugoren Feb 19 at 12:53

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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