PowerShell v3+, 99 95 bytes
Brute force approach --
param($y)(1..12|%{$m=$_;2,3,5,7,11,13,17,19,23,29,31|?{(date "$m-$_-$y").DayofWeek-eq3}}).Count
Takes input $y
, loops from 1
to 12
, stores the month temporarily into $m
, then loops over every prime from 2
to 31
. For each of those, we construct a Get-Date
of that particular day, then select only those with DayOfWeek
-eq
ual to 3
(i.e., Wednesday). Encapsulates that all in a parens to formulate an array, and takes the .Count
thereof.
Alternatively, mathematical approach --
PowerShell v3+, 105 bytes
param($y)(16,19,18,20,16,18,19)[($a=(date "1-1-$y").DayOfWeek)]+(1,-3,0,1,2)[$y%5]*($a-in0,2,3,4)*!($y%4)
Winds up being just a hair longer than the brute force approach, but I'm including it here since it may be beneficial to others.
Again takes input $y
as the year. This time we're performing strictly math operations based on the first day of the year. We first calculate what day of the week that is, and store that into $a
for use later. That indexes into the first array, which gets us the number that is usually correct. We have to add to that a second index based on whether it's a potential leap year, whether it's a Sunday, Tuesday, Wednesday, or Thursday, and based on what the year is.
This is based on the following observation. The first column is what day of week January 1st is, the second is the usual output. Unless the year is one of the middle numbers, then it's the number in parens instead. The final column describes how the %5 indexing works.
Jan-1 -> # ... Except if $y= (then it's this number) | $y % 5 =
Sun -> 16 ... 1928 1956 1984 etc. (17) | 3
Mon -> 19
Tue -> 18 ... 1924 1952 1980 etc. (20) | 4
Wed -> 20 ... 1936 1964 1992 etc. (17) | 1
Thur -> 16 ... 1920 1948 1976 etc. (17) | 0
Fri -> 18
Sat -> 19
Note: Both of these assume en-us
is the current PowerShell setting for culture/date information. The date formatting and DayOfWeek
number may need to be adjusted accordingly for other culture variants.