55
\$\begingroup\$

Write program or function which will take left and right value of dice as integers (1-6) and return value on top.

Dice layout:

 +---+
 | 1 |
+---+---+---+---+
| 2 | 3 | 5 | 4 |
+---+---+---+---+
 | 6 |
 +---+
 ,^.
< ́ 5 `> <-- Top value
|`._, ́|
.6 | 4, <-- Side values
 `.|, ́

So inputting 6 4 will return 5.

Order is important:

2 3 -> 1
3 2 -> 6

Program doesn't have to work with invalid input values.

To discourage obvious approach (using table with all combinations), using any builtin text encoding or de/compression routines or base encoding or anything else similar to reduce size is not allowed. Note that using table is still allowed and rolling your own decompression is allowed too, as long as it's not done using some ready library function.

For reference purposes, here's a table of all combinations (i.e. all possible inputs and outputs):

23, 35, 42, 54 -> 1
14, 31, 46, 63 -> 2
12, 26, 51, 65 -> 3
15, 21, 56, 62 -> 4
13, 36, 41, 64 -> 5
24, 32, 45, 53 -> 6

Shortest code wins, and standard loopholes apply.

asked Jan 8, 2015 at 7:39
\$\endgroup\$
2
  • \$\begingroup\$ so I can use a table with all combination - 1 ^^? \$\endgroup\$ Commented Jan 8, 2015 at 8:17
  • \$\begingroup\$ Yes, you can use table. But you cannot use builtin compression routines to make it smaller. \$\endgroup\$ Commented Jan 8, 2015 at 8:40

16 Answers 16

65
\$\begingroup\$

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)

×ばつ-

Blatantly stolen from above J answer.

TI-Basic, 14 by Timtech

7fPart((A3B-AB3)/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 (削除ここまで) 21 by Martin Büttner, fixed by MarcMush

a\b=(3a^5*b^4-a^3)b%7

Try it online!

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 Raine

?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

Jelly, 9 by caird coinheringaahing

_×ばつ3%7

Try it online!

Exactly the same as the J and APL answers, but in reverse

\$\endgroup\$
7
  • 1
    \$\begingroup\$ FWIW, (ab)**5 % 7 == (ab)**-1 % 7 == a^b^7 for all a,b in 1..6 such that a != b and a+b != 7. \$\endgroup\$ Commented Jan 8, 2015 at 17:44
  • \$\begingroup\$ @PeterTaylor Indeed, I found that expression by using **5 as a proxy for inverting modulo 7. \$\endgroup\$ Commented Jan 8, 2015 at 17:46
  • 2
    \$\begingroup\$ I've been losing sleep over the "why" of this amazing polynomial. Perhaps the math.SE folks can help. math.stackexchange.com/questions/1101870/… \$\endgroup\$ Commented Jan 12, 2015 at 22:02
  • 1
    \$\begingroup\$ I wrote up a derivation on math.SE: math.stackexchange.com/a/1101984/24654 \$\endgroup\$ Commented Jan 13, 2015 at 7:09
  • 1
    \$\begingroup\$ You can rewrite the APL train as 7|3×××+×-, pronounced: 7-remainder of 3 times the product times the sum times the difference (between the two numbers). \$\endgroup\$ Commented Jan 17, 2015 at 1:29
59
\$\begingroup\$

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.

answered Jan 8, 2015 at 9:16
\$\endgroup\$
6
  • \$\begingroup\$ CJam - 26 - ri:Ari:B^7A7A-e<B7B-e<)=*^ \$\endgroup\$ Commented Jan 8, 2015 at 9:22
  • \$\begingroup\$ I can save a char off of min(a,7-a) by doing a^7*(a>3), but I feel like there should be a yet shorter way. Any ideas? \$\endgroup\$ Commented Jan 8, 2015 at 9:31
  • \$\begingroup\$ Ooh, there's a/4*7^a... \$\endgroup\$ Commented Jan 8, 2015 at 9:41
  • 11
    \$\begingroup\$ I never realized that dice face bits had this property. Nice one! \$\endgroup\$ Commented Jan 8, 2015 at 9:43
  • 1
    \$\begingroup\$ @user694733 It works out very fortuitously that 6 is two below a power of two. \$\endgroup\$ Commented Jan 8, 2015 at 9:44
9
\$\begingroup\$

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

answered Jan 8, 2015 at 9:08
\$\endgroup\$
5
  • \$\begingroup\$ Could you explain how this works? Same idea as ep1024 had? \$\endgroup\$ Commented Jan 8, 2015 at 9:17
  • \$\begingroup\$ @user694733 not at all. Explanation added. \$\endgroup\$ Commented Jan 8, 2015 at 9:21
  • \$\begingroup\$ Yeah, I saw the time. I was just wondering if it's similar, because he had explanation on it, and I have no idea how CJam works. \$\endgroup\$ Commented Jan 8, 2015 at 9:29
  • \$\begingroup\$ @Optimizer I want to get started on CJam too, any general direction you can point me at for tutorials etc? I see some examples but they hardly have any explaination :( \$\endgroup\$ Commented Jan 8, 2015 at 14:00
  • \$\begingroup\$ The link above have some examples and a link to the main website which has explanations of the language keywords. Other than that, search here with cjam keyword to learn from existing answers. \$\endgroup\$ Commented Jan 8, 2015 at 14:01
5
\$\begingroup\$

LESS, 62 bytes

Uses the algorithm in this post:

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

It could be shorter if the integer value was used, but to get it to display I needed to use the CSS content property which required variable interpolation.

Nonetheless, it's not often that a CSS preprocessor language is used for code golf!

To use with some HTML, you'd do this:

p::after { .x(1, 3); }
<p>Number on top: </p>
answered Jan 10, 2015 at 10:58
\$\endgroup\$
4
\$\begingroup\$

Pyth, 30 bytes

K"23542 31463 12651 "h/x+K_Kz6

Requires the two digits as input, with no space in between (ex. 23 not 2 3).

Explanation:

Any two digit sequence that lies within 23542 represents two sides that have 1 on top. Likewise, 31463 for 2, etc. Reversing this string gives the sequences for 4 through 6.

This code just does a lookup in the string "23542 31463 12651 15621 36413 24532", divides the index by 6, and increments to determine what the top side must be.

Test online here.

Thanks to @FryAmTheEggman for tips on golfing this.

answered Jan 8, 2015 at 9:08
\$\endgroup\$
1
  • \$\begingroup\$ Some pyth-related golfs: J"23542 31463 12651 "h/x+J_Jscz)6 Ping me if some of it is confusing. Prefer K and J for assigning values, h is unary +1, s on a list of strings is jk. (Also, if allowed, just using a string like 23 as the input would be best) \$\endgroup\$ Commented Jan 8, 2015 at 22:20
3
\$\begingroup\$

Takes a similar approach as es1024 with a different lookup string:

JavaScript (ES6), (削除) 73 (削除ここまで) (削除) 72 (削除ここまで) 61 bytes

t=(l,r)=>-~('354233146312651215623641332453'.search([l]+r)/5)

JavaScript (ES5), (削除) 88 (削除ここまで) (削除) 87 (削除ここまで) 77 bytes

function t(l,r){return -~('354233146312651215623641332453'.indexOf([l]+r)/5)}

CoffeeScript, (削除) 71 (削除ここまで) 62 bytes

(削除) And just for the fun of it, the code is 1 byte shorter in CoffeeScript as ES6 due to the permitted omission of parentheses (削除ここまで)

Due to the use of the -~ trick, this turned out to be the same number of characters as ES6.

t=(l,r)->-~('354233146312651215623641332453'.indexOf([l]+r)/5)
answered Jan 8, 2015 at 9:10
\$\endgroup\$
5
  • 1
    \$\begingroup\$ Save 1 byte: ''+l+r => [l]+r \$\endgroup\$ Commented Jan 8, 2015 at 10:04
  • \$\begingroup\$ @edc65 Thanks! Oh how JavaScript behaves when adding different types \$\endgroup\$ Commented Jan 8, 2015 at 10:09
  • 1
    \$\begingroup\$ Yes, operator + is weird. But what about operator ~? 1+Math.floor => -~. Also, search instead of indexOf. \$\endgroup\$ Commented Jan 8, 2015 at 10:16
  • \$\begingroup\$ Interesting. And I knew about search but it's only for ES6. \$\endgroup\$ Commented Jan 8, 2015 at 17:27
  • \$\begingroup\$ Actually, String.prototype.search has been part of JavaScript since ECMAScript 3rd Edition, so you can change your answer. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… \$\endgroup\$ Commented Aug 2, 2016 at 14:29
3
\$\begingroup\$

J (9)

Uses the algorithm from this post.

7|3***+*-

Tree graph of the function (might clear some things up):

 f=:7|3***+*-
 f
7 | 3 * * * + * -
 5 !: 4 < 'f'
 ┌─ 7 
 ├─ | 
──┤ ┌─ 3 
 │ ├─ * 
 └───┤ ┌─ * 
 │ ├─ * 
 └───┤ ┌─ +
 └───┼─ *
 └─ -

Demonstration:

 3 f 5
1
 4 f 6
2
 2 f 6
3
 2 f 1
4
 1 f 2
3
 4 f 5
6
answered Jan 10, 2015 at 10:49
\$\endgroup\$
0
\$\begingroup\$

PHP, 81 bytes

Same as my JavaScript solution:

function t($l,$r){echo(int)(1+strpos('354233146312651215623641332453',$l.$r)/5);}
answered Jan 8, 2015 at 9:54
\$\endgroup\$
0
\$\begingroup\$

Lua 118

Had to restore last version because of a bug I can't find, nor have time to look for it.

z=io.read;o={"","","34","5 2","2165","46 13",""," 31064"," 5612"," 2 5"," 43"}a=z();b=z();print(o[a+b]:sub(a,a))

Still working on this though.

answered Jan 8, 2015 at 9:15
\$\endgroup\$
3
  • \$\begingroup\$ I tested this here, and it seems to return 4 with 2 3. \$\endgroup\$ Commented Jan 8, 2015 at 9:40
  • \$\begingroup\$ indeed.. weird. ill look into it. \$\endgroup\$ Commented Jan 8, 2015 at 9:43
  • \$\begingroup\$ @user694733 Fixed it :) \$\endgroup\$ Commented Jan 8, 2015 at 10:08
0
\$\begingroup\$

JavaScript (ES6), 79 bytes

Not the shortest but I tried a different approach than currently in the answers.

f=(a,b)=>[a,b,7-a,7-b].reduce((p,v,i,r)=>p?p:'2312132'.indexOf([v]+r[i+1])+1,0)
answered Jan 8, 2015 at 14:36
\$\endgroup\$
0
\$\begingroup\$

Lua, 89 bytes

A straightforward port of xnor's Python solution.

x=require('bit32').bxor
function(a,b)c=a*a*b%7;return x(a,x(b,2<c and c<5 and 7 or 0))end
answered Jan 9, 2015 at 2:15
\$\endgroup\$
0
\$\begingroup\$

Bash, 85

This doesn't compete golf-wise with @xnor's magic polynomial. But I think this is another interesting way to calculate the answer:

g(){
((d[1ドル2ドル]))||{
d[1ドル2ドル]=3ドル
g 2ドル 1ドル $[7-3ドル]
g 2ドル 3ドル 1ドル
}
}
g 1 2 3
echo ${d[1ドル2ドル]}

Specifically we know the the following about dice:

  • If the left face is 1 and the right face is 2, then the top face is 3
  • Rotation around opposite vertices by 120° gives some more triples of face values. E.g we rotate {l=1,r=2,t=3} once we get {l=2,r=3,t=1} and rotating again we get {l=3,r=1,t=2}
  • The sum of opposite faces is always 7

Combining the above recursively (using {1,2,3} hardcoded as a starting point), we can generate the entire mapping of {l,r}->t for all possible values. This answer defines a recursive function g() that populates a full array such that d[lr]=t. The recursive function is initially called with {1,2,3} and recurses all over the whole cube until there are no more array elements that have not been set. The function recurses into itself in two ways:

  • with l and r swapped and t subtracted from 7 (opposite faces)
  • with {l,r,t} rotated to {r,t,l}

It then does a simple array lookup of the values required.

answered Jan 12, 2015 at 4:51
\$\endgroup\$
0
\$\begingroup\$

Dyalog APL, 9 bytes

Blatant character substitution of ɐɔıʇǝɥʇuʎs's J solution:

×ばつ-

Edit: I later noticed that this exact solution was suggested by ngn on Jan 17, 15.

 the division remainder when divided by seven of
 | three times
 | | the product of the arguments
 | | times \┌───┐
 | | \ ┌───┤ ×ばつ │
┌────┐ ┌────┐ ┌─┴─┐ └───┘ ┌───┐
│ 7| ├───┤ ×ばつ ├───┤ ×ばつ │ ┌───┤ + │ - the sum of the arguments
└────┘ └────┘ └─┬─┘ ┌─┴─┐ └───┘ 
 └───┤ ×ばつ │ ---- times
 └─┬─┘ ┌───┐
 └───┤ - │ - the difference between the arguments
 └───┘

TryAPL online!

answered Aug 7, 2016 at 7:27
\$\endgroup\$
0
\$\begingroup\$

Julia, 26 bytes

f(a,b)=a$b7ドル*(2<a^2*b%7<5)

or

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

or

f(a,b)=3*a*b*(a+b)*(a-b)%7
\$\endgroup\$
0
\$\begingroup\$

Common Lisp, 45 bytes

(lambda(a b)(mod(* 3 a b(-(* a a)(* b b)))7))

Try it online!

Port of xnor solution.

answered Dec 5, 2017 at 12:48
\$\endgroup\$
0
\$\begingroup\$

C# (Visual C# Interactive Compiler), 49 bytes

x=>1+("3542331463126512156236413"+x).IndexOf(x)/5

Try it online!

-1 byte thanks to @GB!

The input is a 2 character string containing the visible left and right digits.

Below is the solution that I came up with independently. Leveraging the lookup string from rink.attendant.6's JavaScript answer, I was able to shave off 5 bytes (but now our answers are pretty similar ;)

C# (Visual C# Interactive Compiler), 55 bytes

x=>1+"42354 31463 51265 21562 41364 24532".IndexOf(x)/6

Try it online!

answered Jan 28, 2019 at 22:20
\$\endgroup\$
1
  • 1
    \$\begingroup\$ 49 bytes by using ("3542331463126512156236413"+x) instead of the full string \$\endgroup\$ Commented Jan 30, 2019 at 14:19

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.