Tell me more ×
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.

Please write a program that takes as input two numbers 'day of the month' and 'month number' for any day of this year (2012) and outputs day of the week. Examples:

% ruby ./golf.rb 14 07 # 14th of July 
"Sat"
% ruby ./golf.rb 14 7  # the same
"Sat"
% ruby ./golf.rb 01 12 # Dec 1
"Sat"
% ruby ./golf.rb 31 12 # Last day of the year
"Mon"
  • Output format should be like Mon, Tue, Wed, Thu, Fri, Sat, Sun, not less than 3 letters
  • Do not use date libs/modules, just math and logic
  • Wins the shortest script in any language.
share|improve this question
1  
Please post a scoring criteria or use the "code-golf" tag if the shortest code should win. Othwerwise your question might very soon be closed! – vsz Jul 14 '12 at 20:33

9 Answers

up vote 3 down vote accepted

GolfScript (46 44 chars)

~.5*1$8>+2/\3<++7%"WedThuFriSatSunMonTue"3/=

Calculation can be more efficient than lookup if the days are rotated. I doubt that the mapping to day names can get shorter, but it may still be possible to shave a character or two off the hash function.

However, my best idea for how to do it, finding a power which starts with a suitable string, doesn't look like a contender. After about 9 CPU-days of brute forcing I found a couple of solutions, but they're also 44 chars. The faster one is

~16795 33303?`=+7%"WedThuFriSatSunMonTue"3/=
share|improve this answer

C++ (142) (135) (129 chars)

main(){string s[]={"Mon","Tue","Wen","Thu","Fri","Sat","Sun"};int d,m,t[]={0,5,1,1,4,6,2,4,0,3,5,1,3};cin>>d>>m;cout<<s[(d+t[m]+15-(m<3))%7];}

The requirement that the letters Mon, Tue etc. appear made it quite bad, otherwise it would be only 84 chars. I'll search a golf for the strings...

Hm, trying to golf the string only made it 2 chars longer, but I find it more aesthetically pleasing.

main(){char s[]={"MonTueWenThuFriSatSun"};int d,m,t[]={0,5,1,1,4,6,2,4,0,3,5,1,3};cin>>d>>m;d=((d+t[m]+15-(m<3))%7)*3;s[d+3]=0;printf("%s",s+d);}

Well, this for my first entry at a golf contest, I have still much to learn...

HA! Got it!

main(){char s[]={"MonTueWenThuFriSatSun"},t[]={"0511462403513"};int d,m;cin>>d>>m;d=((d+t[m]-33-(m<3))%7)*3;s[d+3]=0;printf("%s",s+d);}

with a well set compiler and some luck we might chop another 3 characters, by using char* instead of char[], but it will crash on most systems. Anyway, it doesn't matter, as I believe soon someone will post a solution in J or K with less than 10 characters, as usual :P

I'll never give up!

main(){char s[]={"MonTueWenThuFriSatSun0511462403513"};int d,m;cin>>d>>m;d=((d+s[m+21]-33-(m<3))%7)*3;s[d+3]=0;printf("%s",s+d);}
share|improve this answer
It's a leap year this year... ;-) (and my J solution's currently about 75 chars). – Gareth Jul 14 '12 at 21:40
@Gareth: Even if I optimized better for that, there is no chance to beat J. Requiring to write "main(){}", the variable declarations and input/output requires 38 characters, versus nearly nothing in J. – vsz Jul 14 '12 at 21:44
1  
Don't try to beat a non-existent answer, just make your code as small as possible given the questions constraints. In this case the question specifically says "2012" so you could change your month offsets to '401462403513' and take out the -(m<3) to save 6 characters. My C++ is pants but I think you can also use main(d,m){ to initialize your variables and save another 4. If you change your day order so that Wed comes first I think you can get rid of the -33 too. – Gareth Jul 14 '12 at 22:07
"char s[]" ==> "char *s" – Behrooz Jul 16 '12 at 11:47
This isn't a valid C++ program, main needs a return type and you are using cin without std:: and without including iostream. – Bunnit Jul 17 '12 at 3:07
show 6 more comments

c, 101 chars

d,m;main(){scanf("%d %d",&d,&m);printf("%.3s\n","SunMonTueWedThuFriSat"+(d+".034025036146"[m])%7*3);}
share|improve this answer
main(d,m) and scanf("%d%d" save 2 chars. – ugoren Jul 23 '12 at 7:24

APL (57 56)

D M←⎕⋄3↑'MonTueWedThuFriSatSun'↓⍨3×7|D+⍎M⌷'512503514624'
share|improve this answer
I reckon it's hard to bit APL with Ruby or Python :-) – Artem Ice Jul 15 '12 at 0:12

Python3 (93) (86)

print("MTWTFSSouehraunenuitn"[eval('%s+%s+14'%(input(),"0512573514624"[int(input())]))%7::7])

Thanks to vsz. That is just his idea translated to python (plus comments, plus python-tricks).

print("MTWTFSSouehraunenuitn"[(int(input())+int("0512573514624"[int(input())]))%7::7])
share|improve this answer
1  
I don't understand why you're adding 14 if you're just going to do %7 to the result? – Gareth Jul 14 '12 at 23:19

Ruby, 75 74

Ok, my ruby:

a,b=$*.map &:to_i;p:MonTueWedThuFriSatSun[(a-:x365274263153[b].to_i)%7*3,3]

Saved one char:

a,b=$*;p:MonTueWedThuFriSatSun[(a.to_i-:x365274263153[b.to_i].to_i)%7*3,3]
share|improve this answer

Python (130 chars)

d=raw_input().split()
n=int(d[0])+sum([31,29,31,30,31,30,31,31,30,31,30,31][:int(d[1])-1])-1
print 'SMTWTFSuouehranneduit'[n%7::7]

It's rather longish for Python, but I like it.

share|improve this answer

Factor 98

: day ( x x -- x )
{ 0 3 6 5 2 7 4 2 6 3 1 5 3 } nth - 7 mod "MonTueWedThuFriSatSun" 3 group nth ;

Output:

( scratchpad ) 23 7 day

--- Data stack:
"Mon"
share|improve this answer

C, 96 chars

Reads from standard input. Usage: echo 23 7 | ./a.out

main(a,b){
    scanf("%d%d",&a,&b);
    a+=b*30.56-(b>2);
    puts("Thu\0Fri\0Sat\0Sun\0Mon\0Tue\0Wed"+a%7*4);
}

The formula b*30.56, rounded down, gives the accumulated number of days before each month, assuming a 30-day February. -(b>2) corrects for 2012's 29-day February.

share|improve this answer

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.