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.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Given a year, write the shortest program that outputs how many friday the 13ths there are in that year.

Input: You may accept the year either through stdin or as an argument to your program. If a date pre-dates the Gregorian calendar your program can have undefined behaviour(likewise for any invalid input).

Output: an integer to standard out which is how many friday the 13ths are in that year.

Rules: None. Use whatever language, and whatever libraries you like

NOTE: this is different(though similar) from Next Friday the 13th which I found while checking if there's already a duiplicate

Code Golf so shortest code wins.

share|improve this question
What is the required range of input? If it goes much before 1800, what assumptions should be made about switchover from Julian to Gregorian calendar? – Peter Taylor Dec 10 '13 at 22:47
@PeterTaylor I hadn't thought about it. If a date pre-dates gregorian then you can have undefined behaviour. – Cruncher Dec 11 '13 at 14:05
The first countries to adopt the Gregorian calendar did so in October 1582, following the bull of Gregory himself. Countries to adopt the new calendar late did not change until the 20th century, for example Greece introduced it on 1 March 1923. – Jeppe Stig Nielsen Dec 11 '13 at 14:16
@JeppeStigNielsen I don't know much about calendars and such. Whether they adopted them or not doesn't change what the gregorian dates are. Libraries should be able to calculate dates from quite a ways back I presume? – Cruncher Dec 11 '13 at 14:17
I am being offtopic here, I guess. Many libraries written by Anglo-American programmers use September 1752 as the "correct" time of change of calendars. This was when the British Empire changed. The new calendar was kept when U.S.A. was founded, of course. (As a curiosity, some SQL software has 1753 as the minimal year since they don't want to cope with the September 1752 issue.) However, using September 1752 is highly anglocentric. You are right Gregorian dates are the same whether they were used historically or not. That is the so-called proleptic Gregorian calendar. – Jeppe Stig Nielsen Dec 11 '13 at 14:38

25 Answers 25

up vote 11 down vote accepted

Mathematica 49 46 45 44 42

As a pure function: 42 chars





As a named function: 44 chars





share|improve this answer
One character shorter: f=DayName@{#,m,6}~Table~{m,12}~Count~Friday& – Mr.Wizard Dec 11 '13 at 10:25
@Mr.Wizard Yes. It surprises me that Mathematica can parse the multiple cases of infix notation. – DavidC Dec 11 '13 at 13:26
David it surprises me that you haven't seen my (over)use of this conjoined notation. :^) (Examples: (1), (2)) – Mr.Wizard Dec 11 '13 at 18:42

Ruby, 49 48 47 46


Edit: Shaved a character by going back a week, thanks to Jan, and another by switching from to

Edit: At the expense of obfuscating it a bit more, I can get to 46 with

share|improve this answer
one-char saving if you count the numbers of fridays the 6th – Jan Dvorak Dec 10 '13 at 21:53
@JanDvorak clever! – histocrat Dec 10 '13 at 22:11
why 6? I didn't get it. – NARKOZ Dec 11 '13 at 8:28
If the 6th is a friday, then the 13th is also a friday – TwiNight Dec 11 '13 at 9:26

Powershell, 68 63 58 52 50

Thanks Iszi for the tip.

$n=$args;(1..12|?{!+(date $n-$_).DayOfWeek}).Count

Using the fact that if the 1st day in the month is Sunday, the 13th will be Friday.

I've also tried:

(1..12|?{!+(date $args-$_).DayOfWeek}).Count

but it's not the same $args inside the script block.

share|improve this answer
I like the idea of using the first day of the month. – Cruncher Dec 10 '13 at 21:54
Nice trick, there. The @ is unnecessary, though. – Iszi Dec 10 '13 at 23:51
Another thing, though I'm guilty of the same in a lot of my scripts. The challenge does specify that the input can come from an argument. Replace $n with $args in the loop, and you can do without $n=read-host; entirely. Saves 8. Remove @, as mentioned above, and you're down to 54. – Iszi Dec 11 '13 at 0:08
Correction: Comes down to 52! – Iszi Dec 11 '13 at 0:18
Trying to figure out why your second script won't work and I'm at a loss. What's interesting is that I can change out $args for $input, thus feeding the year in from the pipeline, and the script will run but it always outputs 3. – Iszi Dec 12 '13 at 1:27

R 76 72 57

share|improve this answer
Can easily get this down 4 by replacing your "%a %d")=="Fri 13" with "%w%d)=="513") by using dow as a number, and removing the spaces. – chmullig Dec 11 '13 at 3:01
much appreciated! – flodel Dec 11 '13 at 3:11
+1 Though doing the seq only on the month is actually shorter here! sum(format(as.Date(paste(scan(),1:12,13,sep="-")),"%w%d")=="513")is only 65 characters! – plannapus Dec 11 '13 at 8:36
Thanks! Found even more! – flodel Dec 11 '13 at 11:08
wow I wouldn't have guessed that < would coerce a character to an integer. Nice trick! – plannapus Dec 11 '13 at 13:35

C 301+ 287

main(int x,char**v){char p[400],*a[]={"abbababbacaacbac","bacabbb","baabbaca","abbb","aabbacaac","abbbbcaac","abbbbaabb"},*b="adcadcadcaebcadcadcafbcadcadcagbcadcadcadc";int c=0,i,y=atoi(v[0]);for(i=0;i<42;i++)strcpy(&p[c],a[b[i]-'a']),c+=strlen(a[b[i]-'a']);printf("%d",p[y%400]-'`');}

Not the shortest answer, but uses no libraries.

share|improve this answer
Hey, would you be willing to provide the ungolfed answer with an explanation? I'm interested in what exactly you did – Cruncher Dec 11 '13 at 14:07
@Cruncher, it's a lookup table on the basis that the Gregorian calendar follows a 400-year cycle. – Peter Taylor Dec 11 '13 at 14:20
More explicitly (and longer), C#: static char GetNumberOfFriday13s(int year) { const string perpetualCalendar = "1221212213113213122221122131122121221311321312222112213112212122131132131222211‌​221311221212213113213112213113213122221122131122121221311321312222112213112212122‌​131132131222211221311221212213113213122213113213122221122131122121221311321312222‌​112213112212122131132131222211221311221212213113213122221122213122221122131122121‌​221311321312222112213112212122131132131222211221311221212213113213122221122131"; return perpetualCalendar[year % 400];. Won't work for negative years. – Jeppe Stig Nielsen Dec 11 '13 at 15:01
Cute! As a small bug, v[0] should be v[1]. You can also golf this a bit; consider using strcat, storing characters to directly print in a[], and subtracting numeric constants instead of character constants. :) – user1354557 Dec 11 '13 at 17:23
I improved the compression as well: main(int x,char**v){char p[400],*a[]={"1221212213113213","2131222","21122131","1222","112213113","1222231‌​13","122221122"},*b="adcadcadcaebcadcadcafbcadcadcagbcadcadcadc";*p=0;for(;*b;b++‌​)strcat(p,a[*b-97]);putchar(p[atoi(v[1])%400]);} (215 chars) – user1354557 Dec 11 '13 at 18:55

C (151 145 137 131 130 chars)

I am surprised to see that there is only one other solution that doesn't use built-in calendar tools. Here is a (highly obfuscated) mathematical approach, also in C:

f(x){return(x+(x+3)/4-(x+99)/100+!!x)%7;}main(int x,char**v){int y=atoi(v[1])%400,a=f(y+1);putchar('1'+((f(y)&3)==1)+(a>2&&a-5));}

(The above compiles in GCC with no errors)

Alternative solution: C (287->215 chars)

I rather enjoyed Williham Totland's solution and his use of compression. I fixed two small bugs and tweaked the code to shorten its length:

main(int x,char**v){char p[400],*a[]={"1221212213113","213122221122131","12213113","22213113","22221122","2131"},*b="abababafcbababafdbababafebababab";*p=0;for(;*b;b++)strcat(p,a[*b-97]);putchar(p[atoi(v[1])%400]);}
share|improve this answer

bash 47 36

seq -f$1-%g-6 12|date -f-|grep -c ^F

Thanks @DigitalTrauma for saving 10 chars by using seq with default start to 1.

date -f<(printf "%s\n" $1-{1..12}-6)|grep -c ^F

(Previous version using echo present a bug because of the empty line when <(echo $1-{1..12}-6$'\n'). So this function worked fine until today is a Friday.

Lets see:

set -- 2013
seq -f$1-%g-6 1 12|date -f-|grep -c ^F

date -f<(printf "%s\n" $1-{1..12}-13)|grep -c ^F

Is is locale dependant, si if it don't work, you may have to

export LANG=C


LANG=C date -f<(printf "%s\n" $1-{1..12}-13)|grep -c ^F

Into a function; +7 -> 43

f(){ seq -f$1-%g-6 12|date -f-|grep -c ^F;}

f 2013

for i in {2010..2017};do echo $i $(f $i) ;done
2010 1
2011 1
2012 3
2013 2
2014 1
2015 3
2016 1
2017 2

Bonus: +78 -> 121

From there, if my function become:

f(){ o=();for t in $(seq -f$1-%g-6 12|date -f- +%a,%b);do [ "${t:0:1}" = "F" ]&&o+=(${t#*,});done;echo ${#o[@]} ${o[@]};}


f(){ o=();
     for t in $(seq -f$1-%g-6 1 12|date -f- +%a,%b);do
         [ "${t:0:1}" = "F" ]&&o+=(${t#*,})
     echo ${#o[@]} ${o[@]}

for i in {2010..2017};do echo $i $(f $i) ;done
2010 1 Aug
2011 1 May
2012 3 Jan Apr Jul
2013 2 Sep Dec
2014 1 Jun
2015 3 Feb Mar Nov
2016 1 May
2017 2 Jan Oct
share|improve this answer
This seems to be locale-dependent. – Peter Taylor Dec 11 '13 at 14:17
Yes, This is based on default C. But there is a bug... – F. Hauri Dec 11 '13 at 14:36
Save a char by unquoting your printf format string and escaping the \ instead: %s\\n – Digital Trauma Apr 8 '14 at 21:37
Or use seq to drop 8 chars: date -f<(seq -f$1-%g-6 1 12)|grep -c ^F – Digital Trauma Apr 8 '14 at 21:40
Actually, you can shave off 2 more chars. If you omit the starting sequence number, seq will start at 1 by default, which it what you want: seq -f$1-%g-6 12|date -f-|grep -c ^F – Digital Trauma Apr 9 '14 at 16:36

Not using any libraries or built-in date functions:

Golfscript – 51

14%' [3/=RI[)a%:*.'\=5%

' [3/=RI[)a%:*.' could as well be 'feefefgeeffgfe'

Python – 82

Essentially the same algorithm.

l=lambda y:y/4-y/100+y/400

This exploits the fact that, calender-wise, there are only 14 different years, which are distinguishable by their last day and whether they are leaping. l calculates the number of leap years up to its argument (if the Gregorian calendar extended backwards to the year 1). (2*i+3*l(i)-l(i-1))%14 is short for l(i)-l(i-1)+(i+l(i))%7*2, where l(i)-l(i-1) tells us whether the argument is a leap year and i+l(i) sums up the shifts of the last day (one in a normal year, two in a leap year).

share|improve this answer
Since this is my first golfscript golf, I would appreciate any hints on further golfing it down. – Wrzlprmft Apr 10 '14 at 14:27
I was thinking about such a solution utilizing the fact that there's only 14 unique years actually, but wasn't sure the best language to make it competetive. I think this is the shortest answer with no libraries. If leap years were uniformly every 4 years, you might be able to win with this – Cruncher Apr 10 '14 at 15:36

Python2.7 90 86

from datetime import*
print c

Monday the 9th may not have quite the same ring to it but works just as well.

Edit: A year and a half to notice that date is shorter than datetime :)

share|improve this answer
Really nice solution! – leancz Dec 11 '13 at 16:20
You can save a char by doing from datetime import* – user80551 Apr 8 '14 at 15:49

JavaScript, 70

f=function(a){b=0;for(c=12;c--;)b+=!new Date(a,c,1).getDay();return b}
share|improve this answer
and why it is -1? – Lukasz 'Severiaan' Grela Dec 11 '13 at 11:03
Looks good! You can save a few more bytes, by removing ,b,c from the function declaration (it's ok to leak vars for golf!), also as b is cast as a Number you can += the result of test instead of the &&b++: b+=/^F/.test(new Date(a,c,6)). However, you can save another byte, using !new Date(a,c,1).getDay() (this works because getDay returns 0 for Sunday, and if the 13th is a Friday, the 1st will be a Sunday) instead of the test which altogether should save you 7 bytes! – Dom Hastings Dec 11 '13 at 17:11
@DomHastings : thx for your tips !!! – guy777 Dec 11 '13 at 21:27


64 characters

{+/6={x-7*x div 7}(.:')x,/:(".",'"0"^-2$'$:1+!:12),\:".13"}[0:0]

Reads from stdin

share|improve this answer
Ok, just what is going on here? :P – Williham Totland Dec 11 '13 at 11:31
Read in year, build list of dates of 13th day of every month, test day of week = friday, sum resulting list of booleans – slackwear Dec 11 '13 at 13:25

Common Lisp (CLISP), 149

    (loop for i from 1 to 12 count 
        (= 4 (nth-value 6 
                (encode-universal-time 0 0 0 13 i
                    (parse-integer (car *args*)) 0))))))
share|improve this answer
Oh god, I never could read lisp.. – Cruncher Dec 11 '13 at 14:09

C# 110 101 93 92

int f(int y){int c=0;for(int i=1;i<13;i++)c+=new DateTime(y,i,8).DayOfWeek>0?0:1;return c;}

C# Linq 88

int g(int y){return Enumerable.Range(1,12).Count(m=>new DateTime(y,m,8).DayOfWeek==0);}

Thanks to Jeppe Stig Nielsen for linq and suggestion of checking for sunday on the 8th.

Thanks to Danko Durbić for suggesting > instead of ==.

share|improve this answer
Instead of c+=(int)new DateTime(y,i,13).DayOfWeek==5?1:0;, use the equivalent c+=new DateTime(y,i,8).DayOfWeek==0?1:0;. The trick is to subtract 5, because then you can get rid of the cast to int, and also the number 8 has one digit less than the number 13. Sunday the Eighth! – Jeppe Stig Nielsen Dec 11 '13 at 12:48
With Linq: int g(int y){return Enumerable.Range(1,12).Count(m=>new DateTime(y,m,8).DayOfWeek==0);}. Of course as a lambda this is y=>Enumerable.Range(1,12).Count(m=>new DateTime(y,m,8).DayOfWeek==0). – Jeppe Stig Nielsen Dec 11 '13 at 12:55
You can save one character by comparing .DayOfWeek<1. – Danko Durbić Dec 11 '13 at 22:04
@DankoDurbić This can apply to the c# answer but not sure how to apply it to linq . – Kami Dec 12 '13 at 11:02
My mistake; apparently you can't compare DayOfWeek with any other integer than 0 - error CS0019: Operator '<' cannot be applied to operands of type 'System.DayOfWeek' and 'int'. – Danko Durbić Dec 12 '13 at 12:38

K, 42

{+/1={x-7*x div 7}"D"$"."/:'$+(x;1+!12;1)}


k){+/1={x-7*x div 7}"D"$"."/:'$+(x;1+!12;1)}'1776 2012 2013 2014
2 3 2 1
share|improve this answer

Bash (52 47 characters)

for m in {1..12};do cal $m $Y;done|grep -c ^15
share|improve this answer

PHP, 82

<?for($i=1,$c=0;$i<13;$i++)$c+=(date("N",mktime(0,0,0,$i,1,$argv[1]))==7);echo $c;

Based on

"Any month that starts on a Sunday contains a Friday the 13th, and there is at least one Friday the 13th in every calendar year."


share|improve this answer

Rebol, 63

f: 0 repeat m 12[d: do ajoin["6-"m"-"y]if d/weekday = 5[++ f]]f

Usage example in Rebol console:

>> y: 2012
== 2012

>> f: 0 repeat m 12[d: do ajoin["6-"m"-"y]if d/weekday = 5[++ f]]f
== 3

Alternative solution which collects all the Friday 13th in given year is:

>> collect[repeat m 12[d: do ajoin["13-"m"-"y]if d/weekday = 5[keep d]]]
== [13-Jan-2012 13-Apr-2012 13-Jul-2012]
share|improve this answer

Bash and Sed, 39

ncal $1|sed '/F/s/13/\
/g'|grep -c ^\ 2

ncal prints a calendar for the given year with days of the week down the left.

sed with a /g flag subs out all 13s with newlines

grep -c counts the lines that start with " 2" (20 always follows 13)

Thanks to @DigitalTrauma for finding a bug in my old version and proposing a solution!

share|improve this answer
Doesn't quite work for me - Friday lines are only printed once even if they contain more than one 13. – Digital Trauma Apr 8 '14 at 22:16
I think the best I can do with something like this is 38: ncal $1|sed /F/s/13/\\n/g|grep -c ^\ 2 – Digital Trauma Apr 8 '14 at 22:17
@DigitalTrauma You're right. At some point this script was working. let me fix it. – Not that Charles Apr 9 '14 at 14:07
@DigitalTrauma looks like some much longer version was working. thanks for the fix! – Not that Charles Apr 9 '14 at 15:44
Interesting, the unquoted sed expression I proposed works with GNU sed (Linux) but not with BSD sed (OSX). I guess you can gain 1 char at the cost of portability if you choose the GNU version. – Digital Trauma Apr 9 '14 at 16:26

Scala, 76 68 characters

In 78 chars:

def f(y:Int)=0 to 11 count(new java.util.GregorianCalendar(y,_,6).get(7)==6)

Nothing out of ordinary, except for using magical numbers for DAY_OF_WEEK = 7 and FRIDAY = 6.

68 character version:

def f(y:Int)=0 to 11 count(new java.util.Date(y-1900,_,6).getDay==5)

Yes, Java changed values of day of the week constants between API's.

share|improve this answer
It's a shame new java.util.GregorianCalendar has to be so long :( – Cruncher Apr 10 '14 at 15:32

Python 195 / 204

Works only for previous years, because monthdatescalendar returns a calendar for the given year until now. I think there is a lot of optimizing potential left :).

import calendar, sys
for m in range(1,12):
 for w in c.monthdatescalendar(int(sys.argv[1]),m):
  for d in w:
   if d.weekday() == 4 and == 13:

Another solution, works for every date but it isn't smaller:

import datetime,sys
for o in range(f.toordinal(), l.toordinal()):
 if == 13 and d.weekday() == 4:
share|improve this answer
In your first example the range should be (1,13) otherwise you'd miss December Friday 13ths, like in 2013. – leancz Dec 11 '13 at 11:50
You didn't even bother golfing. Remove some of those spaces. – mbomb007 Apr 29 '15 at 15:20

Python(v2) 120

import datetime as d,sys
for m in range(1, 13):
    if d.datetime(int(sys.argv[1]),m,6).weekday()==4: s=s+1
print s
share|improve this answer

Perl + lib POSIX 55

With the idea of not looking for 13th but first, and as sunday is 0 this let save 3 chars! Thanks @ Iszi and Danko Durbić!


Could compute 2010 to 2017 (for sample) in this way:

perl -MPOSIX -pE '$==$_;$_=grep{!strftime"%w",0,0,0,1,$_,$=-1900}(0..11)' <(
    printf "%s\n" {2010..2017})

(Ok, there is no newline, but that was not asked;)

Old post: 63


In action:

for i in {2010..2017};do
    echo $i $(
        perl -MPOSIX -E '
            ' $i );
2010 1
2011 1
2012 3
2013 2
2014 1
2015 3
2016 1
2017 2
share|improve this answer

In Smalltalk (Squeak/Pharo flavour), implement this method in Integer (86 chars)

countFriday13^(1to:12)count:[:m|(Date year:self month:m day:13)dayOfWeekName='Friday']

Then use it like this: 2014countFriday13.

Of course, we could use a shorter name, but then it would not be Smalltalk

share|improve this answer

C++ - Too many bytes :(

I tried a solution which doesn't make use of any date libraries.

I found a pretty cool (if I may say so myself) solution. Unfortunately I can't get it shorter than this, which really bugs me because it feels like there should be a better way.

The solution hinges on this algorithm which is only 44 bytes in itself. Unfortunately I need another 100 bytes to wrap it nicely...

main(int,char**v){int f=0,d,m,y;for(m=1;m<13;++m)d=13,y=atoi(v[1]),(d+=m<3?y--:y-2,23*m/9+d+4+y/4-y/100+y/400)%7-5||++f;return f;}

Output through the return code (in C++, using cout or printf or anything like that requires another #include, which would blow up the solution even more).

Driver / test program:

# Make sure we're not running an old version
rm doomsday.exe

gcc doomsday.cpp -o doomsday.exe

./doomsday.exe 1776
echo 1766: $?

./doomsday.exe 2012
echo 2013: $?

./doomsday.exe 2013
echo 2013: $?

./doomsday.exe 2014
echo 2014: $?

echo `wc doomsday.cpp -c` characters

Output of the driver program:

$ ./test_doomsday 
1766: 2
2013: 3
2013: 2
2014: 1
150 doomsday.cpp characters
share|improve this answer

Not a CodeGolf attempt

Iterator Function SpecificDayOfTheWeekInYear(Year As Integer, DayOfTheWeek As DayOfWeek ) As IEnumerable(of Date)
  Dim FirstDayOfTheYear = New Date(Year,1,1)
  Dim CurrentDay = FirstDayOfTheYear.AddDays( DayOfTheWeek - FirstDayOfTheYear.DayOfWeek )
  If CurrentDay.Year < Year Then CurrentDay = CurrentDay.AddDays(7)
  While CurrentDay.Year = Year
    Yield CurrentDay 
  End While
End Function

Which makes looking for Friday the 13th's simple.

Dim FridayThe13ths =  From d in SpecificDayOfTheWeekInYear(2013,DayOfWeek.Friday )
                     Where d.Day=13

or a much simpler

Iterator Function YieldDayInMonth(Year As Integer, Day As Integer) As IEnumerable(of date)
  For M=1 To 12
   Yield New Date(Year,M,Day )
End Function

This makes the coding thus.

Dim f13 = YieldDayInMonth( 2013, 13).Where( Function(d) d.DayOfWeek = DayOfWeek.Friday)
share|improve this answer
Why are you posting "Not a CodeGolf attempt" on a code golf? That seems a bit off topic and pointless. – Tim Seguine Apr 10 '14 at 18:55
@TimSeguine Bit like posting any entry is pointless, not like is ever going to "win" one of these is it? – Adam Speight Apr 10 '14 at 20:08
It's more about cleverness than winning. If people like your entry, then you are likely to get upvotes even if you don't win. Choosing not to golf on a code golf question seems like not even trying. – Tim Seguine Apr 10 '14 at 20:11
Relevant meta post: I am not the only one who downvotes when things don't follow the spec. – Tim Seguine Apr 18 '14 at 15:56

Your Answer


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.