tags:

views:

622

answers:

11

given an X, what math is needed to find its Y, using this table?

x->y
0->1
1->0
2->6
3->5
4->4
5->3
6->2

language agnostic problem

and no, i dont/cant just store the array, and do the lookup.

yes, the input will always be the finite set of 0 to 6. it wont be scaling later.

+2  A: 
unsigned short convertNumber(unsigned short input) {
  if (input <= 1) { return !input; } //convert 0 => 1, 1 => 0
  return (8-input); //convert 2 => 6 ... 6 => 2
}
Dave DeLong
very practical approach
Kugel
+15  A: 

It looks like:

y = (x * 6 + 1) % 7

Paul R
This is perfect.
ChaosPandion
+1 this is the purest answer so far, since it doesn't require a conditional statement
Dave DeLong
+1  A: 

Homework?

How about:

y = (x <= 1 ? 1 : 8) - x
zildjohn01
+32  A: 

This:

y = (8 - x) % 7

This is how I arrived at that:

x  8-x  (8-x)%7
----------------
0   8     1
1   7     0
2   6     6
3   5     5
4   4     4
5   3     3
6   2     2
Guffa
+1: Nice answer - fewer operations than mine
Paul R
So you are saying that you used common sense and logic to derive an answer to your problem? Who would have thought????
ChaosPandion
As for why they are equivalent: in modulus 7, `6 == -1` and `8 == 1`, so `x*6 + 1 == (-1)x + 1 == (-1)x + 8`
BlueRaja - Danny Pflughoeft
+1  A: 

and no, i dont/cant just store the array, and do the lookup.

Why not?

yes, the input will always be the finite set of 0 to 6. it wont be scaling later.

Just use a bunch of conditionals then.

if (input == 0) return 1;
else if (input == 1) return 0;
else if (input == 2) return 6;
...

Or find a formula if it's easy to see one, and it is here:

if (input == 0) return 1;
else if (input == 1) return 0;
else return 8 - input;

Here's a way to avoid both modulo and conditionals, going from this:

y = (8 - x) % 7

We know that x % y = x - floor(x/y)*y

So we can use y = 8 - x - floor((8 - x) / 7) * 7

IVlad
@|V|lad: what's the point removing modulo if you use a div ?
kriss
@kriss: it's mostly a theoretical achievement, but in rare cases you might not even have a modulo function or it might be slower than division.
IVlad
@|V|lad: I just wanted to point out that mod and div are usually the same low level operation `modiv` at processor level, hence your suggestion is not very much interesting as there is other ways to avoid both % and /. But indeed I know of (poorly designed) languages where you just have +-*/ (never saw mod slower than div).
kriss
+4  A: 

Combining the ideas in Dave and Paul's answer gives the rather elegant:

y = (8 - x) % 7`

(though I see I was beaten to the punch with this)

Stephen Canon
+21  A: 

0.048611x^6 - 0.9625x^5 + 7.340278x^4 - 26.6875x^3 + (45 + 1/9)x^2 - 25.85x + 1

Sometimes the simple ways are best. ;)

Matthew Flaschen
+1 for absurdity
BlueRaja - Danny Pflughoeft
@Matthew: Dare I even ask how you derived this result?
Nathan Ernst
hh polynomial regression :-)?
Kugel
@Nathan, I have discovered a truly marvelous proof that these are the precise coefficients. However, this margin is too narrow to contain it.
Matthew Flaschen
That could be wrapped in a general-purpose polynomial class with an array of coefficients, and a length. There would be an evaluate method and....
phkahler
@Nathan - He got this via polynomial interpretation http://en.wikipedia.org/wiki/Interpolation
Kragen
+6  A: 

Though it seems a bunch of correct answers have already appeared, I figured I'd post this just to show another way to have worked it out (they're all basically variations on the same thing):

Well, the underlying pattern is pretty simple:

x y
0 6
1 5
2 4
3 3
4 2 
5 1
6 0

y = 6 - x

Your data just happens to have the y values shifted "down" by two indices (or to have the x values shifted "up").

So you need a function to shift the x value. This should do it:

x = (x + 5) % 7;

Resulting equation:

y = 6 - ((x + 5) % 7);
Dan Tao
+1 for showing your work :)
Glenn Sandoval
Nice. If it was homework, I bet this is the pattern that you were supposed to see. :)
Guffa
+12  A: 
phkahler
+1 Very cute solution.
Stephen Canon
+1 How did you get this?
Kugel
@Kugel: hint convert magic number to binary and you may see the light)
kriss
Guffa
+20  A: 
int f(int x)
{
    return x["I@Velcro"] & 7;
}
wtf? please explain.
Kugel
kriss
The fun bit was using grep to try to find words I could stick in the string with the correct lowest three bits.
+1 for getting an actual WTF? and making me laugh. Kugel is learning a lot today, and that's what SO is all about ;-)
phkahler
Haha, based on the WTFs/min principle (http://www.osnews.com/story/19266/WTFs_m), this would have to be some of the worst code ever. *I* like it, though.
Dan Tao
+1  A: 

What about some bit-fu ?

You can get the result using only minus, logical operators and shifts.

b = (x >> 2) | ((x >> 1) & 1)
y = ((b << 3)|(b ^ 1)) - x
kriss