C++ (g++), 60 54 4747 40 bytes
1-indexed. f(2)==29.
int f(int n){return(n/8|n/4|n)%2+(n^n/8)%2+29;%2-(n==2)+30;}
Solution from k-map, which simplified to A=w+x+z and B=zw'+z'w. A was negated and became a subtraction.
int f(int n){ //N is a 4-digit binary number wxyz.
return (n/8|nn^n/4|n8) %2 //Add 1 if (w OR x ORXOR z)
+- (n^n/8n==2) %2 //AddSubtract 1 if !(w XOROR x OR z), which simplifies to (w'x'z'),
+ 29; //Addwhich 29is only satisfied when N is 0000 or 0010.
//Since n is never 0, thethis lengthcondition ofis only satisfied when n==2.
+ 30; //Add 30, the shortestbase month length.
}
At first I tried adding 1 or 2 instead of 1 or 1, but my solution was 87 bytes (if I remember correctly). I tried that with 0-indexing and 1-indexing, but they ended up being the exact same length.
Edit47 bytes: Thanks to Herman L. for the improvement from int f(int n){return(n/8|n/4|n)%2+(n^n/8)%2+29;}
54 bytes: int f(int n){return((n>>3|n>>2|n)&1)+((n^n>>3)&1)+29;}
60 bytes: int f(int n){return(n>>3&1|n>>2&1|n&1)+((n&1)^(n>>3&1))+29;}
Edit: Thanks to Herman L. for the improvement to 54 bytes, I'm glad someone found my approach interesting even though it's clearly not the shortest!
Edit 2: Thank you to ceilingcat for the suggestionimprovement to use (n/8|n/4|n)%2+(n^n/8)%2
instead of ((n>>3|n>>2|n)&1)+((n^n>>3)&1)
47 bytes. This uses division instead of bit shifting, which saves one byte in each of three places. It also replaces &1
with %2
in two places. Both of these functionally return the last byte of the integer, but the modulo operator has precedence over addition. This means that two pairs of parentheses can be removed, saving four bytes. In total, by mixing arithmetic and bitwise operators, ceilingcat managed to improve the answer by seven bytes!
Edit 3: Another improvement by ceilingcat brings it down six bytes by doing bitwise comparison with 13, -!(n&13)
. Since this is only true in one case, simplified to an equality check.