text:
Happy Birthday to Me!
Happy birthday to Me!
Write a program that prints Happy birthday to me! on its birthday.

The program's birthday is the creation, last modification or compilation time of the program (you choose), and must not be hard-coded.
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.
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%.
It must print only this, and not print anything on any other day.
Count bytes, in UTF-8.
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.

what if i print it on my bday and a celebrity's bday? :P

@TeunPronk, You can't do both. Either use your own birthday, or a celebrity's (or none, and give up the extra credit).

that bonus is a killer - I think the choice between dates and messages is too complex for the 15% to be worth the effort for getting the smallest code size

Agreed; in all attempts I've done to incorporate the bonus the score only goes up (where lower == beter).

@TeunPronk: Only Jon Skeet can :P

Is this a code-golf? If so, you should add that tag.

I saw this in the Hot Questions sidebar and read "Happy Birthday to Mel"...

@nyuszika7h http://codegolf.stackexchange.com/posts/21285/revisions It was tagged codegolf but was changed to challenge. Possibly because of a semi-complex scoring system

@PeterTaylor, why retag to code-challenge? The winner is the lowest byte count, which makes it code golf.

Point 3 makes the winner not lowest byte count, and disqualifies it from being [tag:code-golf]. I meant to mention this when it was in the sandbox, but I may have forgotten.

@PeterTaylor: Huh? Awarding various kinds of score bonuses for extra features is pretty common for [tag:code-golf] questions, and I've never before seen anyone claim that it would disqualify a question from using that tag, as long as the primary scoring criterion is code length.

I'm not sure about the "some celebrity" part. How many celebrities are allowed in the program, and can you subtract 14% for each of them?

@MrLister, one celebrity.

@Izkata Cannot up-vote that enough.

@Izkata, Updated the question in honor of Mel.

@ugoren If Mel Kaye himself post an answer (very unlikely), what it should output in his birthday?

@Victor, whatever answer he'd post, I'll automatically accept.

@IlmariKaronen, the tag wiki excerpt for [tag:code-golf] says "A competition which scores on a mixture of source length and some other criterion should be tagged [code-challenge] instead." I've been retagging questions on this basis for a while now, and no-one's complained before.

@PeterTaylor Wait, are you on a one man crusade to change all [code-golf] questions to [code-challenge] if they say "X points off if you also ..." ?

@PeterTaylor: I just started a meta discussion on this, feel free to join in.

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!

Doesn't it include the year in the comparison? if so, it only works on the 0th birthday.

@ugoren You're right! Thanks for the correction. 2 bytes saved.

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.

And the equals sign and the semicolon are not necessary for the touch version.

<?date(dm,stat(__FILE__)[9])-date(dm)&&die?>Happy birthday to me!

@TimSeguine Thanks for your suggestions! I've incorporated them into my answer, I hope you don't mind.

Of course it is fine, otherwise I wouldn't have suggested it. If your feeling overly thankful, then feel free to upvote my answers to other questions. ;)

I found another mod that trimmed it down to 60, ;) instead of stat(__FILE__)[9] use getlastmod()

@TimSeguine Thanks again. I've also seen that function in the manual, but I didn't know that it accepts 0 parameters :)

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

Thanks to ugoren, ace and nyuszika7h for help.

I think you can escape the ! with \! so you don't need the quotes and save 1 char.

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!

You only need to escape ! in interactive shells, not scripts.

You can save two characters by using [ and ] instead of [[ and ]].

Does it work when the year isn't the same as the creation date?

@ugoren: damn I feel stupid now :D

@nyuszika7h I cannot get that working

Using [ ] instead of [[ ]] should work, are you sure you have spaces between the square brackets and the backticks?

ah, now that the output format is numerical (not 18-02-2014 but 182) the single square brackets seem to work

Don't 11/1 and 1/11 get mixed up?

@ugoren: damn you are good at bug hunting. Fortunately 11/1 and 1/11 won't get mixed up as both %d and %m actually prepend a zero when the value is a single digit - I end up checking 0111 and 1101 for equality. I hope this works for all cases but I'm not sure.

@shiona, Leading zeros are good (unless they mean octal numbers, but I don't think bash does it).

You can use = for comparing strings.

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!");}}

You could save few bytes in the bonus ones by adding ,b="1202"==t after you get the date string and using that instead.

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.

Ah, okay. It's been a while since I've used C#. My bad.

You could shorten the simpler version by comparing dates, not strings. This mens using something like CreationTime.Date == DateTime.Today.

That would only work for today/this year/birthday 0. How would that work for other years?

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.

Happy birthday to, not for ;-) Just saved you another byte :-)

Also, the newline (\n) is not required AFAIK which saves you another 4 bytes ;-)

Yeah... I should stop shooting my own foot :P You're welcome ;)

Does it work when the creation year isn't the same as the current year?

@ugoren Yes, the return d.getMonth()*40+d.getDate(); do not uses the year (so it is thrown away). And I just retested this to be sure that I was not missing something.

@Victor, right, I missed f and though you just compare dates.

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

File name has to be 'f.m'

On your birthday it should say "Happy birthday to you!" :-)

@RobIII:Oops, you'r right, I didn't read carefully enough. Will remove the second version. Thanks!

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.

Why do you need the variable t? Doesn't dir('f.m').date work?

@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, I'm afraid I don't get it. I really don't know Matlab. In most languages, t=dir('f.m');t.date is equivalent to dir('f.m').date.

First, matlab does not support dir('f.m').date and secondly, the behavior of dir depending on whether you call it as dir('f.m') or  t = dir('f.m'). Please see http://www.mathworks.de/de/help/matlab/ref/dir.html for details.

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 :)

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])?

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: 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

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!

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

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!"}

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?

You can remove the write command - With just "happy birthday to me!" it will print it out.

Your quite right. I should know that.

@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).

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.

beating you by 56 bytes so far =P

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. ;)

Can you quote the error and your OS? I guess it's just not crossplatform.

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.

Unfortunately, only works correctly for maximum of seven years or so, until you run into the first leap year after the atime.

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.

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}

Your code fails on leap years, for dates after February.

@ugoren right you are. Fixed that, but lost a lot of points :(

But now I've reclaimed most of those! =)

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.

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.

Are you sure that's UTF-8?

OP explicitly states you should use UTF-8. That's 66 characters and 68 bytes.

If you want to claim it's 46 bytes, write it in 46 bytes. As it is now, it's 68 bytes.

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.

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)+"!")

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!");
    }
}

You use x only twice; var x="MMdd"; + ToString(x) + ToString(x) = 15 whereas ToString("MMdd"); + ToString("MMdd"); only costs 12.

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 ;-)

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

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.

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!");
    }
}

Day of year doesn't work well with leap years.

@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.

If I were compiling after February 28th I could change the String format to "%tm%td" at a six point character cost

JavaScript (node.js) - 100 bytes
(require('fs').fstatSync(4).mtime+1).match(Date().substr(4,6))&&console.log('Happy birthday to me!')

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

You can get a bonus for your birthday OR a celebrity. Not both.

@ugoren Scoring doesn't state it's an exclusive or, so I'm using the logical meaning of or.

Powershell, 82 bytes

see also answers from Chris J and SpellingD

"Happy birthday to me!"|?{(gv My* -v|% M*|% p*h|gci|% l*w*e|% D*r)-eq(date|% D*r)}

where
gv My* -v|% M*|% p*h|gci|% l*w*e|% D*r

is the combinations of shortcuts and aliases for the expression:
Get-Valiable MyInvocation -value|% MyCommand|% Path|Get-ChildItem|% LastWritetime|% DayOfYear

that equivalent a canonical form:
(Get-ChildItem $MyInvocation.MyCommand.Path).LastWritetime.DayOfYear

Powershell, 119 bytes - 14% = 102.34 Points
filter e{$_-eq(date|% D*r)}$('me'|?{gv My* -v|% M*|% p*h|gci|% l*w*e|% D*r|e}
'Prof'|?{3|e})|%{"Happy birthday to $_!"}

At January 3, the script display Happy birthday to Prof!. If this script is saved on January 3, two greetings will be displayed.

authors: Денис Дюканов

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
Analysing the most common words in a text, and replacing them with a single byte
This is a very crude text encoding algorithm I came up with the other day. It won't work if the text has more than 256 different characters in it – but it does support Unicode, at least in my Python implementation.
The algorithm:

Find all the unique characters in the text. Let's call this list, unique-chars.
Break the text into a sequence of tokens, which can be either words (continuous runs of alphanumeric characters, and apostrophes) and symbols (anything that isn't a word). If there's two symbols (say, a comma and a space), take each only once.
Sort the tokens, most commonly occurring first. Then, take the top (256 - length of unique-chars). Put the two lists – unique-chars, and most-common-tokens – together into one. Let's call this list substitution-table.
Iterate through each token. If it's present in substitution-table, take the index in which this token is found, and convert it into a character. Otherwise, iterate through each letter in the token, and perform the same character conversion.

This way, the most common words become one byte long; and those which are not as common, stay of the same length. I know, this is not very efficient. But it works.
For reference, use King James' Bible, by Project Gutenberg; 4 452 069 bytes, MD5: 3b83dd48fa7db8df0819108f6d50f64f. Download here.
The processed version is 3 422 006 bytes, MD5: 17c52a22abe48dd4135a577e2a4aff8d. Download here.
No restrictions apply on the language used, external libraries/programs, dirty tricks, or operating system.
My Python 3 implementation runs in about 3.3–3.5 seconds, in average. Speed has precedence on everything else. Compiled language implementations, especially in C, would be appreciated. A solution in APL or Perl would be most welcome, I'm curious how they'd look like.
As for how to time the solution, I'd say, time 30 executions (possibly cleaning the RAM after each execution, in case caching occurs), and report both the lowest time (which is indicative limit as for how long it takes the machine to run the program in the best conditions) and the rest of times, for completeness' sake. Obviously, this is not perfectly accurate, but it'll do for an indicative value.
That said, happy coding~!

It already exists and it's called 'LZMA' for short. wikipedia link: http://en.wikipedia.org/wiki/Lempel–Ziv–Markov_chain_algorithm

This seems flawed as a compression algorithm, because the decompressor doesn't have the substitution table.

@PeterTaylor the substation table can be exported as JSON in a separate file, but that doesn't really matter. What I want to do here is the compression only.

@IsmaelMiguel thanks for the link! But, from what I gather, LZMA is a generic compression tool. Mine is tailored specifically for text (I wasn't clear enough in the question?). Reading the "Dictionary coder" article on Wikipedia, I realise how my technique is similar (everything has already been invented…) – but I am not aiming to re-implement LZMA. I'd like to implement a simple (although less efficient) scheme.

It works better for text, so, I guess it is more focused on text. And according to your description, a LZMA encodes is "fine".

@Jetlef Is there a chance that you can provide a smaller example rather than the Gutenberg Bible? Hamlet's soliloquy perhaps? It's a lot to go through...

@WallyWest Sure thing! Here's Poe's "The Raven", it's about 8 Kb.

Perl - 154 bytes (KJB in ~1.94s)
while(<>){push@w,/[\w\']+|\W/g}
\@c{length>1?$w{$_}++?():/./g:$_}for@w;
@t{sort{$w{$b}-$w{$a}}keys%w}=grep!exists$c{$_},map{chr}0..255;
print$t{$_}//$_ for@w

This is substantially golfed, but I can say with confidence that it hasn't affected the performance in any noticable way.
Sample Usage:
$ perl encoder.pl < king-james-bible.txt > kjb.cmp

The created filesize is 3,253,677 bytes, runtime is approximately 1.94 seconds. If you want to test the correctness, you can export a translation table by appending the following three lines of code:
;use Storable;
%u=reverse%t;
store\%u,'trans.tbl'

This will create, and possibly overwrite, a file named trans.tbl in the current working directory. Then, decode with the following script:
#!perl -n0
use Storable;
%t=%{retrieve 'trans.tbl'};
print$t{$_}//$_ for/./sg

Sample usage:
$ perl decoder.pl < kjb.cmp > kjb.txt

The output is exactly 4,452,069 bytes, as expected.

Unrolled and commented
while(<>){      # for each line
  push@w,/[\w\']+|\W/g # tokenize, add tokens to array
}

\@c{            # mark the following chars
  length>1?     # token is 2 or more chars
    $w{$_}++    # increment occurrence in word hash
    ?           # if this word has already been seen
      ()        # mark nothing
    :           # else
      /./g      # mark each char individually
  :             # else
    $_          # mark the single char
}for@w;         # iterate over all tokens

@t{             # create the translation table
  sort{$w{$b}-$w{$a}}keys%w # most frequent words
}=grep!exists$c{$_},map{chr}0..255; # assign to an unmarked char

print           # output
  $t{$_}        # the value in the trans hash
    //          # or, if previous value is undefined
  $_            # output the untranslated string
for@w           # iterate over the tokens previously found

Time analysis
Min: 1.843s
Max: 1.984s
Avg: 1.939s
1.953, 1.953, 1.953, 1.843, 1.921, 1.937, 1.921, 1.953, 1.953, 1.921, 1.937, 1.968, 1.906, 1.984, 1.937, 1.968, 1.953, 1.921, 1.921, 1.937, 1.968, 1.937, 1.890, 1.968, 1.937, 1.953, 1.937, 1.937, 1.937, 1.953
According to profiling, the time usage for each statement is approximately the following:
1.09s:
while(<>){push@w,/[\w\']+|\W/g}
31.3ms:
\@c{length>1?$w{$_}++?():/./g:$_}for@w;
15.6ms:
@t{sort{$w{$b}-$w{$a}}keys%w}=grep!exists$c{$_},map{chr}0..255;
750ms:
print$t{$_}//$_for@w
Note that for the purpose of time usage analysis, the result was actually written to a file. Excluding the final output, or piping to /dev/null instead produces times 600ms to 750ms faster.

Major Performance Gains

The individual characters of a word are marked only the first time the word is seen, instead of every time. As noted by @VadimR, this alone saves around 2s, over 25% of the previous execution time.
The most frequent words are translated with unmarked characters, and marked characters left untranslated. This saves a great deal of time during output, because words not in the translation table can be output directly, without having to translate each individual character.
Tokenizing the file one line at a time - instead of all at once - is quite a bit faster.

+1, it's beautifully golfed, but, because of 'fastest code' tag, I did some benchmarking and found that -40% boost can be gained with 'words' translation caching, and using substr to mark characters. I can add to your answer if you don't mind :-)

@VadimR I think I see what you mean. If a word has already been found, the it isn't necessary to mark its constituent characters again (and again, and again). I can confirm that using /./sg is notably faster than split, but I never thought to try substr.

H-mm, but words not in translation table should be translated letter by letter, shouldn't they? Looking at what you've changed, - I meant something slightly different.

I already nearly wrote an answer (or I'd prefer adding to yours), when I found a little flaw in my tests. Now I'm waiting till I get back to my 'normal' PC with 64-bit linux OS for proper testing - so I'll elaborate on details later.

@VadimR There's no reason that a single character cannot be represented by the character itself. In fact, it seems like a quite logical thing to do.

Oh, I see. Yes, it's reasonable.

With your marking characters of unseen words only, my ways to improve performance are no longer relevant. But, if you are interested, what I meant was: (1) re-use %w hash (to hold translations, not counts) - no longer needed as you don't translate most words - but it gave 10-15% boost; (2) use substr to access every single character instead of regexp - another 20-25%. Even now, when you mark chars in unseen words only, accessing every character with substr gives the same speed.

Consider first line of revision 5 code. Replacing it with $c{substr$s,$_,1}=1 for 0..length($s)-1; @w=$s=~/[\w\']+|./gs; $w{$_}++ for grep {length>1} @w; gives aforementioned  boost (input in $s, next line has [0..255-keys%c] as hash slice range).

C# - 1.4s
I use a different metric for word sorting - 'word.Length -1' as this is the value of how many bytes would be saved by compressing said word.  For example the word 'a' appears a lot, but saves nothing to compress (as it's already kept), and "the" saves twice as much as "at".
//Initial Size 4452066
//Final Size 3186918
//Time 1408 ms

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;

namespace SimpleCommonWordCompressor
{
    class Program
    {
        static void Main(string[] args)
        {
            while (true)
            {
                var data = File.ReadAllText("king-james-bible.txt");
                var sw = Stopwatch.StartNew();

                var uniqueChars = data.Distinct().Select(c => c.ToString()).ToArray();

                var tokens = new List<string>();
                var currentWord = new List<char>();
                Action tryAddWord = () =>
                {
                    if (currentWord.Count > 0)
                    {
                        tokens.Add(string.Join("", currentWord));
                        currentWord.Clear();
                    }
                };
                var charToStringLU = Enumerable.Range(0, 256).Select(i => ((char) i).ToString()).ToArray();
                foreach (var datum in data)
                    if (char.IsLetterOrDigit(datum)) currentWord.Add(datum);
                    else
                    {
                        tryAddWord();
                        tokens.Add(charToStringLU[datum]);
                    }
                tryAddWord();

                var grpTokens = tokens.GroupBy(x => x).ToArray();

                var wordTable = uniqueChars.Concat(grpTokens
                    .OrderByDescending(g => g.Count() * (g.Key.Length - 1))
                    .Select(grp => grp.Key)
                    .Take(256 - uniqueChars.Length)).ToList();

                var wordDict = wordTable.ToDictionary(w => w, w => new[] { (byte)wordTable.IndexOf(w) });
                var charTable = new byte[256];

                for (byte i = 0; i < uniqueChars.Length; i++)
                    charTable[uniqueChars[i][0]] = i;

                var tokenToBinary = grpTokens.ToDictionary
                    (grp => grp.Key, grp =>{
                        byte[] index;
                        if (wordDict.TryGetValue(grp.Key, out index)) return index;
                        var newWordBinary = grp.Key.Select(c => charTable[c]).ToArray();
                        return newWordBinary;
                    });

                var binary = new List<byte>();

                foreach (var token in tokens)
                    binary.AddRange(tokenToBinary[token]);

                sw.Stop();
                Console.WriteLine("Initial Size " + data.Length);
                Console.WriteLine("Final Size " + binary.Count);
                Console.WriteLine("Time " + sw.ElapsedMilliseconds + " ms\n");
                Console.WriteLine("Press enter to run again");
                Console.ReadLine();
            }
        }
    }
}

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/

sort: votes


text:
Detect what programming language a snippet is
Your challenge is to take some source code as input, and output which programming language it is written in.
For example, you could have the input
class A{public static void main(String[]a){System.out.println("Hello, World!");}}

And output
Java

Your two main goals are diversity (how many programming languages you can detect) and accuracy (how good you are at detecting these languages).
For polyglots (programs valid in more than one language), you can decide what to do. You could just output the language that your program thinks is more likely, or you could output an error, or you could output an array of possible choices (which would probably get more upvotes than just an error!).
This is a popularity-contest, because it would be very difficult to specify a different objective winning criterion. Voters, please vote on how many languages it can detect and how accurate it is.

That is impossible, cause print("") can be used in many languages.

@IsmaelMiguel I never said "unambiguously." Sure, some programs run in many languages, but the goal is to identify as many programs as possible.

What you are asking is impossible in my opinion.

With your edit, now it seems more possible.

What about languages that are valid for EVERY input? Like whitespace. This sentence is a valid whitespace program. This whole page is a valid whitespace program.

@IsmaelMiguel You could try detecting how likely the program is Whitespace (tabs, arrangement of chars, etc.). (That's the whole point of this challenge.) Or you could just not detect whitespace ;)

To do this properly you'd need a huge test set and train a classifier.

@marinus Not necessarily; for example, Python could be easily detected by searching for : in the right place. Similarly, PHP/Perl could be detected by $s in certain places, XML/CSS by obviousness, objective-C by its unique syntax, APL by special chars, etc.

Reasonable job for Amazon Mechanical Turk.

Is the input guaranteed to be a valid program? Like some input could be class A{public static void main(String[]a){System.println.out("Hello, World!");}} which is invalid.

Or likewise will HTML input always start with <!DOCTYPE html> followed by the <html>,<body> and other tags (like meta) in their correct order?

@Gaurang Yes, but there could be different class name, different doctype, etc.

@Doorknob And, though I have 5-6 languages ready, I want just want to confirm that will the given code always produce output i.e. have a print() statement?

Related: http://codegolf.stackexchange.com/questions/15372/write-a-program-in-disguise (try testing your submissions on these)

Can we optionally return a list of percentages for which language it is likely written in?

234 text formats - Unix Shell
(not all of them languages - I need to count them carefully)
file $1

I hesitate to post this somewhat smart-a$$ answer, but I don't see anything in the rules banning it and the file shell utility really does do a good job of this.  e.g:
$ file golfscript.rb
golfscript.rb: Ruby module source, ASCII text
$ file template.c
template.c: ASCII C program text
$ file adams.sh
adams.sh: Bourne-Again shell script, ASCII text executable
$

Furthermore you can use the -k option to "keep going" when testing a polyglot:
 -k, --keep-going
         Don't stop at the first match, keep going.  Subsequent matches
         will be have the string ‘\012- ’ prepended.  (If you want a new‐
         line, see the -r option.)

Also, the -l option will give you an idea of how good the algorithm is for differing languages:

$ file -l | grep shell
unknown, 0: Warning: using regular magic file `/etc/magic'
Strength = 280 : shell archive text [application/octet-stream]
Strength = 250 : Tenex C shell script text executable [text/x-shellscript]
Strength = 250 : Bourne-Again shell script text executable [text/x-shellscript]
Strength = 240 : Paul Falstad's zsh script text executable [text/x-shellscript]
Strength = 240 : Neil Brown's ash script text executable [text/x-shellscript]
Strength = 230 : Neil Brown's ae script text executable [text/x-shellscript]
Strength = 210 : Tenex C shell script text executable [text/x-shellscript]
Strength = 210 : Bourne-Again shell script text executable [text/x-shellscript]
Strength = 190 : Tenex C shell script text executable [text/x-shellscript]
Strength = 190 : Bourne-Again shell script text executable [text/x-shellscript]
Strength = 180 : Paul Falstad's zsh script text executable [text/x-shellscript]
Strength = 150 : Tenex C shell script text executable [text/x-shellscript]
Strength = 150 : Bourne-Again shell script text executable [text/x-shellscript]
Strength = 140 : C shell script text executable [text/x-shellscript]
Strength = 140 : Korn shell script text executable [text/x-shellscript]
Strength = 140 : Paul Falstad's zsh script text executable [text/x-shellscript]
Strength = 130 : POSIX shell script text executable [text/x-shellscript]
Strength = 130 : Plan 9 rc shell script text executable []
$

This is file-5.09 (on Ubuntu 12.04)

This actually does pretty well on a 16-language polyglot - https://gist.github.com/riking/9088817

You might as well cut out the middle man and avoid the shell entirely: ln -s /usr/bin/file /usr/local/bin/myspecialtool. If your answer counts, then doesn't this count just as well? (Don't worry, I'm not serious.)

Looks like a standard loophole, i.e. delegating solution to existing program.

18 programming languages, 1002 bytes, accuracy: test for yourself :)
(yep I know this is not code golf, but for the fun of it)
The program searches for iconic code snippets, the checks are ordered in a way that the most clear checks are at the top and programming languages embedded in other programming languages are below (e.g. HTML in PHP).
This obviously fails for programs like System.out.println('<?php');
t = (p) ->
    h = (x) -> -1 != p.indexOf x
    s = (x) -> 0 == p.indexOf x

    if h "⍵" then "APL"
    else if h "<?php" then "PHP"
    else if h("<?xml") and h "<html" then "XHTML"
    else if h "<html" then "HTML"
    else if h "<?xml" then "XML"
    else if h("jQuery") or h "document.get" then "JavaScript"
    else if h "def __init__(self" then "Python"
    else if h "\\documentclass" then "TeX"
    else if h("java.") or h "public class" then "Java"
    else if s("SELE") or s("UPDATE") or s "DELE" then "SQL"
    else if /[-\+\.,\[\]\>\<]{9}/.test p then "Brainfuck"
    else if h "NSString" then "Objective-C"
    else if h "do |" then "Ruby"
    else if h("prototype") or h "$(" then "JavaScript"
    else if h "(defun" then "Common Lisp"
    else if /::\s*[a-z]+\s*->/i.test p then "Haskell"
    else if h "using System" then "C#"
    else if h "#include"
        if h("iostream") or h "using namespace" then "C++"
        else "C"
    else "???"

program = ""
process.stdin.on 'data', (chunk) -> program += chunk
process.stdin.on 'end', -> console.log t program

Usage on node: coffee timwolla.coffee < Example.java
Demo (Online-Demo on JSFiddle):
[timwolla@~/workspace/js]coffee puzzle.coffee < ../c/nginx/src/core/nginx.c
C
[timwolla@~/workspace/js]coffee puzzle.coffee < ../ruby/github-services/lib/service.rb
Ruby
[timwolla@~/workspace/js]coffee puzzle.coffee < ../python/seafile/python/seaserv/api.py
Python

On my computer this outputs nothing, not even on input that should obviously work. Granted, I might be doing something wrong as I've never used Coffeescript before.

@marinus Note that when manually inputting code you need to send an EOF (STRG+D) to trigger execution. Generally: The detector should at least spit out three question marks.

Nope, nothing. Do I need to pass coffee any arguments? I had just tried redirecting files into it, but just running it and going ^D doesn't do anything either.

@marinus Try: npm install coffee-script && node_modules/.bin/coffee timwolla.coffee < timwolla.coffee in a temporary folder, this should spit out APL. (assuming you have a recent version of node and npm installed)

@marinus I just added an online demo on JSFiddle: http://jsfiddle.net/TimWolla/wkJKY/

npm wouldn't work either so obviously it's something about my system. But allright, the fiddle convinced me, have an upvote.

I'll start using lowercase omega more in my non-APL programs.

Sorry dude, but that code is too inaccurate in my opinion.

Another obvious fail is any string with ω.

Bash — about 50 35 bytes per compilable language
Trick is to just compile, then you don't have to worry about linking errors from missing libraries, and it's more forgiving if you just have code snippets.
Thanks to Shahbaz for shorter forms!
gcc -c $1 && (echo C; exit 0)
g++ -c $1 && (echo C++; exit 0)
gpc -c $1 && (echo Pascal; exit 0)
gfortran -c $1 && (echo Fortran; exit 0)

etc...

Since you mention number of bytes per compilable language, you might be interested in lines like: gcc -c $1 && (echo C; exit 0)

Thank you, I'm not very good at really squeezing code!

Sure. The && and || in bash are really useful and help cleanup the code a lot. They are by no means used for obfuscation, so you'd do well to learn them.

You can also pass -fsyntax-only to only check the syntax and skip actual compilation.

Just a few broad generalizations.
I think it's fairly accurate.
This is Ruby btw. Takes (multiline) input from stdin.
puts case $<.read
when /\)\)\)\)\)/
  "Lisp"
when /}\s+}\s+}\s+}/
  "Java"
when /<>/
  "Perl"
when /|\w+|/
  "Ruby"
when /\w+ :- \w+ \./
  "Prolog"
when /^[+-<>\[\],.]+$/
  "brainfuck"
when /\[\[.*\]\]/
  "Bash"
when /~]\.{,/
  "golfscript"
end

I would think #include is a better predictor for c.  What about #!/bin/(ba)?sh for bash/shell scripts?

@DigitalTrauma Yea, I think you're right about #include. For artistic reasons I'm not going to just catch the hash-bang where the name of the language is explicitly spelled out tho.

#include is a comment in ini files and php

@IsmaelMiguel true, but generally it would appear more often in a C-program and I'm generalizing here. But, it messes up the Feng Shui of the program so I took it away. Now it doesn't look at any words at all, just typical traits of the syntax.

Now you have my upvote. And yes, you are right. But i like your answer btw. Try to include vb (searching for /^dim / should do it). And you can go even more crazy and add /^#include <luac(?:.h)?>/ to detect lua inside c.

"/}\s+}\s+}\s+}/"  Looks like I'm no longer a C# programmer...

+1 for having prolog, but no C :)

I would add \$\w+ after the perl one to detect PHP. Also (\w+)::~\1 is usually a C++ destructor

This answer is a proof of concept, that will not likely receive any more work from myself.
It falls short in several ways:

The output is not exactly as the question requests, but close enough and could easily be modified to produce the exact output required.
There are several ways to make the code perform better and/or better ways to represent the data structures.
and more

The idea is to set a list of keywords/characters/phrases that can identify a specific language and assign a score to that keyword for each language. Then check the source file(s) for these keywords, and tally up the scores for each language that you find keywords for. In the end the language with the highest score is the likely winner. This also caters for polyglot programs as both (or all) the relevant languages will score high.
The only thing to add more languages is to identify their "signatures" and add them to the mapping.
You can also assign different scores to different keywords per language. For example, if you feel volatile is used more in Java than in C, set the score for volatile keyword to 2 for Java and 1 for C.
public class SourceTest {

  public static void main(String[] args) {
    if (args.length < 1) {
      System.out.println("No file provided.");
      System.exit(0);
    }
    SourceTest sourceTest = new SourceTest();
    for (String fileName : args) {
      try {
        sourceTest.checkFile(fileName);
      } catch (FileNotFoundException e) {
        System.out.println(fileName + " : not found.");
      } catch (IOException e) {
        System.out.println(fileName + " : could not read");
      }
    }
    System.exit(0);
  }

  private Map<String, LanguagePoints> keyWordPoints;
  private Map<LANGUAGES, Integer> scores;

  private enum LANGUAGES {
    C, HTML, JAVA;
  }

  public SourceTest() {
    init();
  }

  public void checkFile(String fileName) throws FileNotFoundException, IOException {
    String fileContent = getFileContent(fileName);
    testFile(fileContent);
    printResults(fileName);
  }

  private void printResults(String fileName) {
    System.out.println(fileName);
    for (LANGUAGES lang : scores.keySet()) {
      System.out.println("\t" + lang + "\t" + scores.get(lang));
    }
  }

  private void testFile(String fileContent) {
    for (String key : keyWordPoints.keySet()) {
      if (fileContent.indexOf(key) != -1) {
        for (LANGUAGES lang : keyWordPoints.get(key).keySet()) {
          scores.put(lang, scores.get(lang) == null ? new Integer(1) : scores.get(lang) + 1);
        }
      }
    }
  }

  private String getFileContent(String fileName) throws FileNotFoundException, IOException {
    File file = new File(fileName);
    FileReader fr = new FileReader(file);// Using 1.6 so no Files
    BufferedReader br = new BufferedReader(fr);
    StringBuilder fileContent = new StringBuilder();
    String line = br.readLine();
    while (line != null) {
      fileContent.append(line);
      line = br.readLine();
    }
    return fileContent.toString();
  }

  private void init() {
    scores = new HashMap<LANGUAGES, Integer>();

    keyWordPoints = new HashMap<String, LanguagePoints>();
    keyWordPoints.put("public class", new LanguagePoints().add(LANGUAGES.JAVA, 1));
    keyWordPoints.put("public static void main", new LanguagePoints().add(LANGUAGES.JAVA, 1));
    keyWordPoints.put("<html", new LanguagePoints().add(LANGUAGES.HTML, 1));
    keyWordPoints.put("<body", new LanguagePoints().add(LANGUAGES.HTML, 1));
    keyWordPoints.put("cout", new LanguagePoints().add(LANGUAGES.C, 1));
    keyWordPoints.put("#include", new LanguagePoints().add(LANGUAGES.C, 1));
    keyWordPoints.put("volatile", new LanguagePoints().add(LANGUAGES.JAVA, 1).add(LANGUAGES.C, 1));
  }

  private class LanguagePoints extends HashMap<LANGUAGES, Integer> {
    public LanguagePoints add(LANGUAGES l, Integer i) {
      this.put(l, i);
      return this;
    }
  }
}

Javascript - 6 languages - high accuracy
Current Languages: Java, C, HTML, PHP, CSS, Javascript
I work on the principle that whenever an input satisfies a criteria, it is given a score, and based on that score results are given.
Features:

No built-in functions that determine language type used.
Does not straightaway declare the input text is x language on seeing a keyword.
Suggests other probable languages also.

Should you feel that any of your inputs of the programs (that I have done till now) are not caught or get invalid results, then please report and I'd be happy to fix them.
Sample Input 1:
class A{public static void main(String[]a){System.out.println("<?php");}}

Sample Output 1:
My program thinks you have :
Java with a chance of 100%
Php with a chance of 25%
----------------

Explanation:
This should have failed the program and I would have printed PHP, but since my program works on the basis of scores, nothing fails and it easily identifies Java in the first place, followed by other possible results.
Sample Input 2:
class A{public static void main(String[]a){System.out.println("HelloWorld!");}}

Sample Output 2:
Java
----------------

Sample Input 3:
ABCDEFGHIJKLMNOPQRSTUVWXYZ

Sample Output 3:
Language not catched! Sorry.
----------------

The code:
// Helper functions

String.prototype.m = function(condition){
  return this.match(condition);
};

String.prototype.capitalize = function(){
  return this[0].toUpperCase() + this.substr(1);
};

function getFuncName(func){
  var temp =  func.toString();
  temp = temp.substr( "function ".length);
  temp = temp.substr( 0, temp.indexOf("("));
  return temp.capitalize();
}

// Get input
var lang_input = prompt("Enter programming language");

// Max score of 4 per lang

function java(input){
  var score = 0;
  score += input.m(/class[\s\n]+[\w$]+[\s\n]*\{/) ? 1 : 0;
  score += input.m(/public[\s\n]+static[\s\n]+void[\s\n]+main[\s\n]*/) ? 1 : 0;
  score += input.m(/\}[\s\n]*\}[\s\n]*$/) ? 1 : 0;
  score += input.m(/System[\s\n]*[.][\s\n]*out/) ? 1 : 0;
  return score;
}

function c(input){
  var score = 0;
  // if java has passsed
  if(checks[0][1] >= 3)return 0;

  score += input.m(/^#include\s+<[\w.]+>\s*\n/) ? 1 : 0;
  score += input.m(/main[\s\n]*\([\s\n]*(void)?[\s\n]*\)[\s\n]*\{/) ? 1 : 0;
  score += input.m(/printf[\s\n]+\(/) || input.m(/%d/) ? 1 : 0;
  score += input.m(/#include\s+<[\w.]+>\s*\n/) || input.m(/(%c|%f|%s)/) ? 1 : 0;
  return score;
}

function PHP(input){
  var score = 0;
  score += input.m(/<\?php/) ? 1 : 0;
  score += input.m(/\?>/) ? 1 : 0;
  score += input.m(/echo/) ? 1 : 0;
  score += input.m(/$[\w]+\s*=\s*/) ? 1 : 0;
  return score;
}

function HTML(input){
  var score = 0;
  // if php has passed
  if(checks[2][1] >= 2) return 0;

  score += input.m(/<!DOCTYPE ["' \w:\/\/]*>/) ? 1 : 0;
  score += input.m(/<html>/) && input.m(/<\/html>/) ? 1 : 0;
  score += input.m(/<body>/) && input.m(/<\/body/) ? 1 :  0;
  score += input.m(/<head>/) && input.m(/<\/head>/) ? 1 : 0;
  return score;
}

function javascript(input){
  var score = 0;
  score += input.m(/console[\s\n]*[.][\s\n]*log[\s\n*]\(/) ? 1 : 0;
  score += input.m(/[\s\n]*var[\s\n]+/) ? 1 : 0;
  score += input.m(/[\s\n]*function[\s\n]+[\w]+[\s\n]+\(/) ? 1 : 0;
  score += input.m(/document[\s\n]*[.]/) ||
           ( input.m(/\/\*/) && input.m(/\*\//) ) ||
           ( input.m(/\/\/.*\n/) )? 1 : 0;
  return score;
}

function CSS(input){
  var score = 0;
  score += input.m(/[a-zA-Z]+[\s\n]*\{[\w\n]*[a-zA-Z\-]+[\s\n]*:/) ? 1 : 0;
  // since color is more common, I give it a separate place
  score += input.m(/color/) ? 1 : 0;
  score += input.m(/height/) || input.m(/width/) ? 1 : 0;
  score += input.m(/#[a-zA-Z]+[\s\n]*\{[\w\n]*[a-zA-Z\-]+[\s\n]*:/) ||
           input.m(/[.][a-zA-Z]+[\s\n]*\{[\w\n]*[a-zA-Z\-]+[\s\n]*:/) ||
           ( input.m(/\/\*/) && input.m(/\*\//) ) ? 1 : 0;
  return score;
}

// [Langs to check, scores]
var checks = [[java, 0], [c, 0], [PHP, 0], [HTML, 0], [javascript, 0], [CSS, 0]];
//Their scores

// Assign scores
for(var i = 0; i < checks.length; i++){
  var func = checks[i][0];
  checks[i][1] = func(lang_input);
}

// Sort the scores
checks.sort(function(a,b){ return b[1] - a[1]; });

var all_zero = true;

function check_all_zero(index){
  if(checks[index][1] > 0){ all_zero = false; return 0; } // someone is above zero

  // check next index only if it defined, else return zero
  if(checks[index + 1])
    check_all_zero(index + 1);
}

check_all_zero(0);

if(all_zero){
  console.log("Language not catched! Sorry.");
}else {
  var new_arr = [];                   // temp

  checks.map(function(value, index){
    if(value[1] > 0){
      var temp = [getFuncName(value[0]), value[1]];
      new_arr.push(temp);
    }
  });

  checks = new_arr.slice(0);          // array copy, because of mutation

  if(checks.length === 1){
    console.log(checks[0][0]);
  }else{
    console.log("My program thinks you have :");
    checks.map(function(value){
      var prob = (value[1]/4 * 100);
      console.log(value[0] + " with a chance of " + prob + "%");
    });
  }

} // Main else block finish

console.log("----------------");

Python, 4 languages, can you test how accurate this is?
Sorry, but you need to put the source code in a file.
import sys

file = sys.argv[1]

def detect(code: str):

    python_keys = {"#": 1, "print": 2, "def": 5, "with": 5, "in": 2, "tuple": 5, ":": 1.5, "except":5, "str": 1.5, "complex": 4, "_": 2, "match": 3}
    javascript_keys = {"{": 3, "function": 4, "=>": 5, "catch": 2.5, "switch": 2, "var": 5, "let": 5, "const": 5, "//": 2}
    c_keys = {"#include": 5, "#pragma once": 5, "#ifdef": 4.5, "#ifndef": 4.5, "*": 2, "size_t": 3, "{": 4, "struct": 5, "switch": 2, "//": 2}
    html_keys = {"<!--": 5, "<!DOCTYPE":5, "html": 5, "href": 5, ".css": 4, "</": 3, "http": 3}

    langs = ["Python", "JavaScript", "C", "HTML"]
    scores = {lang: 0 for lang in langs}

    for lang in langs:
        score = 0

        for key, value in eval(f"{lang.lower()}_keys").items():
            score += value * code.count(key)

        scores[lang] = score

    return scores

with open(file) as file:
    results = detect(file.read())

if "-l" in sys.argv:
    summed = sum(results.values())
    for lang, score in results.items():
        print(f"{lang}: {100 * score / summed}% likely")
else:
    max_score = max(results.values())
    print(*filter(lambda lang: results[lang] == max_score, results.keys()), sep=", ")

This can also receive the -l flag to list how likely each language is.
Here is it checking itself with the -l flag enabled (on powershell, current directory hidden for obvious reasons):
>py langdetect.py langdetect.py -l
Python: 49.022346368715084% likely
JavaScript: 18.01675977653631% likely
C: 23.18435754189944% likely
HTML: 9.776536312849162% likely