Shortest expression for {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4}

24

2

Given list of integers {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4}. For those who interested these numbers are used in weekday calculation.

Weekday = (m[n] + d + y + y>>2 + y/400 - y/100) % 7;, where m[n] - expression I'm searching, d - day of month, y - year - (month <= 2).

Construct expression consisting of arithmetic, logic and bitwise operators, which will output for positive integer n integer m so that m % 7 equals n-th number in the list.

Branches, ternary operators, table lookups and pointers are not allowed.

Score:
1 - for | & ^ ~ >> << operators
1.1 - for + - < > <= >= == != ! && || operators
1.2 - for * operator
1.4 - for / % operators

Answer with lowest score wins.

Personally I have found:

(41*n)>>4+((n+61)>>4)<<2 with score 6.4. I thought this will be hard to find so provided own expression to start with.

Somnium

Posted 2014-07-16T21:46:37.600

Reputation: 2 537

I guess array dereferencing (and the kin) isn't allowed either? – John Dvorak – 2014-07-16T21:48:09.110

Oh, yes of course, I have edited the question. – Somnium – 2014-07-16T21:49:43.507

6The question would be greatly improved by some motivation. Where do those numbers come from? – Peter Taylor – 2014-07-16T22:32:15.197

table lookups Interesting phrasing I suppose... – ɐɔıʇǝɥʇuʎs – 2014-07-16T23:15:52.603

4

Why not count the %7 in the score? Maybe there's another solution not using %. Is zero positive, negative, both or nothing?

– Thomas Weller – 2014-07-17T06:16:31.313

@ThomasW. %7 needs to be calculated in every case. – Somnium – 2014-07-17T06:21:54.880

Yes, with the rest of the formula you have given in your updated question, this is clear now. Thanks. – Thomas Weller – 2014-07-17T06:22:43.933

@m.buettner Thank you for comment. It's my first question, I thought that own example will be good. Next time I won't steal fun) – Somnium – 2014-07-17T06:24:22.877

What language is the expression supposed to be in? From the examples, I'm assuming C or some C-like language with similar operator syntax (such as C++ or Java), but it would be nice if you could include this information in the challenge (and tag it with the appropriate language tag).

– Ilmari Karonen – 2014-07-17T09:18:25.930

I want to be it in C. However any language is ok if used operators which are in C language. – Somnium – 2014-07-17T09:35:31.507

Answers

34

2 2.2

I love arbitrary precision arithmetic.

0x4126030156610>>(n<<2)

Or, if you don't like hex,

1146104239711760>>(n<<2)

Test:

print([(0x4126030156610>>(n<<2))%7 for n in range(1,13)])
[0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4]

isaacg

Posted 2014-07-16T21:46:37.600

Reputation: 39 268

Could you perhaps make a lookup table with 4*n instead, and save 0.2 points by writing it as n<<2? – xnor – 2014-07-17T00:54:25.970

@xnor Absolutely! Just to to switch from octal to hexadecimal. Just as sec. – isaacg – 2014-07-17T02:04:14.790

Cool. I'm pretty convinced nothing can do better because it would require using only one operation, and they all seem to have too much structure mod 7. My best candidate of integer floor division const/n runs into a contradiction with n=4 and n=8. – xnor – 2014-07-17T02:23:14.057

@xnor Another close one is const%n which could satisfy everything except n=1,2 and 3. – isaacg – 2014-07-17T02:43:06.717

I was gonna do the same thing, but you beat me to it... – ɐɔıʇǝɥʇuʎs – 2014-07-17T05:41:03.577

No way to beat this I think) Btw, how small expression with 32-bit integers is possible? – Somnium – 2014-07-17T06:33:09.570

@user2992539 I don't know what's optimal under your precise rules, but check out Mike Keith's solution here: http://www.merlyn.demon.co.uk/zel-like.htm#Keith

– isaacg – 2014-07-17T07:20:50.067

Rechoosen as accepted because first one with smallest score. – Somnium – 2014-07-17T11:21:13.703

32

2.0

(127004 >> i) ^ 60233

or (score 2.2) :

(i * 3246) ^ 130159

All found with brute force :-)

Arnaud

Posted 2014-07-16T21:46:37.600

Reputation: 8 231

Since this has the same score as isaacg's answer, but doesn't uses 64-bit integers, I'm choosing this as accepted answer. Thank you for answer! – Somnium – 2014-07-17T10:23:54.317

8@user2992539 While it's nice that this answer uses 32-bit integers, you didn't specify this criterion in your challenge, which makes isaacg's answer perfectly valid. Therefore, the two answers tie and I think it's only fair to accept the first one that got this score. (Kudos to Super Chafouin, though, +1!) – Martin Ender – 2014-07-17T10:50:37.940

@m.buettner I have to agree with you. Next time, I will be more careful with description and answer selection. – Somnium – 2014-07-17T11:19:49.600

For others to learn, could you elaborate on how you did the brute force calculation? – Thomas Weller – 2014-07-17T22:07:12.190

@Thomas I just made a double for loop, testing all the values p, q for the formula (p >> i) ^ q, then went to take a coffee, and 10 mn after came to read the results. – Arnaud – 2014-07-18T01:59:14.923

@SuperChafouin: ok, thanks. So you already had a clear pattern in mind and didn't brute force all operators as well. – Thomas Weller – 2014-07-18T06:09:25.240

8

35.3

I suspect this may be the least efficient method to create the list:

1.7801122128869781e+003 * n - 
1.7215267321373362e+003 * n ^ 2 + 
8.3107487075415247e+002 * n ^ 3 - 
2.0576746235987866e+002 * n ^ 4 + 
1.7702949291688071e+001 * n ^ 5 + 
3.7551387326116981e+000 * n ^ 6 - 
1.3296432299817251e+000 * n ^ 7 + 
1.8138635864087030e-001 * n ^ 8 - 
1.3366764519057219e-002 * n ^ 9 + 
5.2402527302299116e-004 * n ^ 10 - 
8.5946393615396631e-006 * n ^ 11 -
7.0418841304671321e+002

I just calculated the polynomial regression. I'm tempted to see what other terrible method could be attempted.

Notably, I could save 3.3 points if the result was rounded. At this point, I don't think that matters.

lochok

Posted 2014-07-16T21:46:37.600

Reputation: 3 139

5

3.2

Zero based solution:

7 & (37383146136 >> (i*3))

One based solution:

7 & (299065169088 >> (i*3))

I initially thought that the %7 operation would be counted as well and % being an expensive operation here, I tried to solve it without it.

I came to a result of 3.2 like this:

// Construction of the number
// Use 3 bits per entry and shift to correct place
long c = 0;
int[] nums = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
for (int i = nums.Length - 1; i >= 0; i--)
{
    c <<= 3;
    c += nums[i];
}
// c = 37383146136

// Actual challenge
for (int i = 0; i < 13; i++)
{
    Console.Write("{0} ",7 & 37383146136 >> i*3);
}

I'd be interested in optimizations using this approach (without %). Thanks.

Thomas Weller

Posted 2014-07-16T21:46:37.600

Reputation: 1 925

This is cool, maybe this will help me some day) How do you think, maybe I should create separate question for whole formula minimization? – Somnium – 2014-07-17T06:45:55.427

1How about (0426415305230 >> (i*3)) & 7? You can see the output digits in reverse order. – CJ Dennis – 2014-07-18T14:51:09.123

@CJDennis: I think there are no octal numbers in C#. – Thomas Weller – 2014-07-18T15:20:26.593

I thought it was just C? I can't see any other reference to C#. – CJ Dennis – 2014-07-19T01:17:21.047

0

Python (3)

Since there are quite a few of these questions these days, I decided to make a program to automatically solve them in 3 (or 2) tokens. Here's the result for this challenge:

G:\Users\Synthetica\Anaconda\python.exe "C:/Users/Synthetica/PycharmProjects/PCCG/Atomic golfer.py"
Input sequence: 0 3 2 5 0 3 5 1 4 6 2 4
f = lambda n: (72997619651120 >> (n << 2)) & 15
f = lambda n: (0x426415305230L >> (n << 2)) & 15
f = lambda n: (0b10000100110010000010101001100000101001000110000 >> (n << 2)) & 15

Process finished with exit code 0

Proof that this works:

f = lambda n: (72997619651120 >> (n << 2)) & 15

for i in range(12):
   print i, f(i)

0 0
1 3
2 2
3 5
4 0
5 3
6 5
7 1
8 4
9 6
10 2
11 4

ɐɔıʇǝɥʇuʎs

Posted 2014-07-16T21:46:37.600

Reputation: 4 449

How does your solver consider the cost of operands? – Thomas Weller – 2014-07-17T22:12:26.250

@ThomasW. It doesn't, it'll always use a right shift, possibly a left shift (if the values aren't 1 bit) and an &. – ɐɔıʇǝɥʇuʎs – 2014-07-18T12:40:14.790