Obscure C syntax for Tomohiko Sakamoto's algorithm

Viewed 114

I stumbled upon this version of the Sakamoto algorithm

dow(m,d,y){y-=m<3;return(y+y/4-y/100+y/400+"-bed=pen+mad."[m]+d)%7;}

I tried it on ideone.com and it actually works. I'm not interested in how the algorithm works, it's the syntax that baffles me.

I consider myself an intermediate C programmer and I have absolutely no idea what's going on in the "-bed=pen+mad."[m] part of the code.

What is that???

4 Answers

That's array subscription on a string literal. Remember that a string literal is actually just a pointer to static memory.

The operation is equivalent to:

int m = 0;
char *str = "-bed=pen+mad.";
str[m];

char is a scalar type, and thus you can do arithmetic with the value.

Ok I got it. The algorithm needs a lookup table for the value to add, based on the month.

"-bed=pen+mad." is a string, which is an array of char

Its values are

0: ASCII '-' not relevant since the month 0 does not exist
1: ASCII 'b' = 98
2: ASCII 'e' = 101
3: ASCII 'd' = 100
4: ASCII '=' = 61
5: ASCII 'p' = 122
6: ASCII 'e' = 101
7: ASCII 'n' = 110
8: ASCII '+' = 43
9: ASCII 'm' = 109
10: ASCII 'a' = 97
11: ASCII 'd' = 100
12: ASCII '.' = 46

The month m is used as index so that if we're for instance in February i.e index 2, the position 2 of the array is char 'e' and the value 101 gets added to the equation.

It gets confusing because the plus and the equal make it look like an equation and the apparent words like bed, pen and mad trick the brain into looking for a meaning that isn't there. It's just a bunch of characters.

Whoever wrote this was hardcore

"-bed=pen+mad."[0] is '-' or, probably, 45
"-bed=pen+mad."[1] is 'b' or, probably, 98
...
"-bed=pen+mad."[12] is '.' or, probably, 46
"-bed=pen+mad."[13] is '\0' or 0

As that value is eventually going to be (...) % 7

"-bed=pen+mad."[0] % 7 // probably 3
"-bed=pen+mad."[1] % 7 // probably 0
...
"-bed=pen+mad."[12] % 7 // probably 4
"-bed=pen+mad."[13] % 7 // 0

The expanded version of Tomohiko Sakamoto's dayofweek() is on Wikipedia.

"-bed=pen+mad." is an array of constant chars that can also be written this way:

const char tab[] = { '-', 'b', 'e', 'd', '=', 'p', 'e', 'n', '+', 'm', 'a', 'd', '.', 0 };

Considering this is ASCII, "-bed=pen+mad." may also be written:

const char tab[] = { 45, 98, 101, 100, 61, 112, 101, 110, 43, 109, 97, 100, 46, 0 };

Now, considering the end result will eventually be % 7, this can also be written:

const char tab[] = { 3, 0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4, 0 };

And now, we see that for any month m between 1 and 12, "-bed=pen+mad."[m] is the same (congruent % 7) as tab[m] which is exactly the same as t[m-1] in the expanded version.

Related