Determine dice value from side view

There's a nice polynomial expression modulo 7 for the third side given two sides a and b.

$${3(a^3b - ab^3) \mod 7}$$

or factored

$${3ab(a^2-b^2) \mod 7}$$

The modulo 7 maps to a remainder in {0,1,2,3,4,5,6}.

I explain why it works in this Math SE answer, though I do think there probably is a cleaner argument I'm missing. The only other two-term polynomial that works is

$${(3a^5b^5 - a^3b) \mod 7}$$

which I originally found by transforming my bit-bashing into arithmetic operations, then did a brute-force search over polynomials of this form to find the nicer one.

Please feel free to add ports of this into your favorite language; this is a CW post.

J, 9 by Synthetica

7|3***+*-

See my post

Dyalog APL, 9 by ngn (typo fixed by Adám)

7|3×××+×-

Blatantly stolen from above J answer.

TI-Basic, 14 by Timtech

7fPart((A³B-AB³)/21

Pyth, 16 by FryAmTheEggman

M%*3-*H^G3*^H3G7

Defines a function g of two values.

Golfscript, 18 by Peter Taylor (old polynomial)

~1$*.5?3*@.*@*- 7%

CJam, 18 by Martin Büttner (ported from Peter's GolfScript) (old polynomial)

l~1$*_5#3*@_*@*m7%

Mathematica, 20 by Martin Büttner

Mod[+##(#-#2)3##,7]&

Yes, that's a unary plus, and no, there's no shorter way that doesn't use a unary plus.

dc, 21 by Toby Speight

sb7+d3^lb*rlb3^*-3*7%

I have to add 7 to a to ensure the difference is always positive (dc has a signed % operator).

Julia, 24 23 by Martin Büttner

f(a,b)=3a*b*(a^2-b^2)%7

CoffeeScript, 28 26 by rink.attendant.6

x=(a,b)->3*a*b*(a*a-b*b)%7

JavaScript (ES6), 28 26 by rink.attendant.6

x=(a,b)=>3*a*b*(a*a-b*b)%7

Essentially the same as CoffeeScript.

Python 28, by xnor

lambda a,b:3*a*b*(a*a-b*b)%7

Bash, 31

Nothing special:

echo $[3*($1**3*$2-$1*$2**3)%7]

or alternatively:

echo $[3*$1*$2*($1*$1-$2*$2)%7]

Another (longer but perhaps interesting) approach.

Nim, 36 by Sillesta

proc(x,y:int):int=3*x*y*(x*x-y*y)%%7

Java 7, 46 44 by rink.attendant.6

int f(int a,int b){return(a*a-b*b)*a*b*3%7;}

Java 8, 25 23 by Kevin Cruijssen

a->b->(a*a-b*b)*a*b*3%7

PHP, 49 47 by rink.attendant.6

function x($a,$b){echo($a*$a-$b*$b)*3*$a*$b%7;}

Batch, 52 unclemeat

set/aa=(3*(%1*%1*%1*%2-%1*%2*%2*%2)%%7+7)%%7
echo %a%

CMD does not support true modulus natively (so can't handle negative numbers) - hence %%7+7)%%7.

LESS (as a parametric mixin), 62 60 by rink.attendant.6

.x(@a,@b){@r:mod(3*@a*@b*(@a*@a-@b*@b),7);content:~"'@{r}'"}

See my post below.

05AB1E, 10 8 by Emigna (-2 bytes by Kevin Cruijssen)

nÆs`3P7%

Try it online.

Haskell, 31 27 25 by Generic Display Name

a#b=3*a*b*(a*a-b*b)`mod`7

Try it online!

Excel, 27 by by Wernisch

=MOD(3*(A1^3*B1-A1*B1^3),7)

Excel VBA, 25 by Taylor Scott

?3*[A1^3*B1-A1*B1^3]Mod 7

Forth (gforth) 41 by reffu

: f 2>r 2r@ * 2r@ + 2r> - 3 * * * 7 mod ;

Try it online!

C#, 23 by Kevin Cruijssen

a=>b=>(a*a-b*b)*a*b*3%7

Python, 30

lambda a,b:a^b^7*(2<a*a*b%7<5)

No lookups, just bit bashing.

The opposite faces come in pairs that are three-bit complements of each other, meaning that they XOR to 7.

1,6
2,5
3,4

Given two faces from one set, we want to get a face from the other set. For (1,2,3), we can do this with XOR (^). So, ^ gives the right answer up to three-bit complement, meaning x^7. We can conditionally complement by x^7*_.

To decide whether or not to take the complement (XOR with 7), we check whether the triplet violates the right-hand rule. That means, that a,b goes in the reverse cyclic order of

1,6
2,5
3,4

treating each line as one of the three categories. Since the elements in each line are negatives mod 7, we can "hash" them by doing x*x%7.

1,6 -> 1
2,5 -> 4
3,4 -> 2

Each line is obtained from the cyclically previous by multiplying by 4 modulo 7, so we can check whether this relationship holds for (b,a) to decide whether to complement: a*a%7==b*b*4%7.

This is equivalent to checking whether, modulo 7, a**2 * b**(-2) equals 4. Since b**6 equals 1 modulo 6, this is equivalent to a**2 * b**4. Since the other possible value is 2 (by checking cases), we can check if it's 4 by comparing to 3.


CJam, 43 28 bytes

No idea if a full table based approach will be shorter, but here goes:

l_~^56213641532453s@S-#)g7*^

Input like

2 3

Output:

1

This is a mixture of my previous algorithm to determine the correct face out of 2 faces and xnor's approach of xors.

Try it online here

Tags:

Code Golf