Rolling the Dice

So, I was rolling dice a while ago and thought of a challenge.

Given the cube with a net taken from input and a list of moves, find the square on the bottom at the end.

Cube Map

I will use this image for the examples here.


You take in a string with a list of moves. The string contains only the capital ASCII letters N, S, W, and E. These correspond to rolling the cube one step into that direction.

In the picture, one N would make the bottom face a 6. In this image, North is away from the camera, South is towards, East is right, and West is left.

You also take in a string in the following format: 1P 2P 3P 4P 5P 6P, where each P is a position from N, S, W, E, T, and B. T & B are bottom and top.

The numbers are the face with that number, and the letter represents the position the face is in. In case it isn't clear, the net will always be ordered by the number, so 1P 2P 3P 4P 5P 6P, never 2B 1T 3N 4S 5W 6E.

The position in the image is 1S 2B 3E 4W 5T 6N.


Your program should output a number representing the bottom side.

Test Cases

(nothing), 1S 2B 3E 4W 5T 6N -> 2
N, 1S 2B 3E 4W 5T 6N -> 6
NS, 1S 2B 3E 4W 5T 6N -> 2
NWS, 1S 2B 3E 4W 5T 6N -> 2
NWSNWS, 1S 2B 3E 4W 5T 6N -> 2
NWSS, 1S 2B 3E 4W 5T 6N -> 3
NNNNNN, 1S 2B 3E 4W 5T 6N -> 5
SNWEEWS, 1N 2T 3E 4W 5B 6S, 6
SNEEWS, 1N 2T 3W 4S 5B 6E, 4

Other Rules

You may also assume the cube is on a infinite flat plane, probably with some sort of friction.

Standard loopholes disallowed, even though I can't find any.

For invalid input, your code may do anything except start the apocalypse.

Because this program should fit on my dice, it should be as small as possible. I count in bytes, with some exceptions for languages like Folders.

  • 2
    \$\begingroup\$ Does the first test case with (nothing) -> 2 mean that no net is provided, or should there be a net there somewhere? \$\endgroup\$
    – Sp3000
    Dec 13 '15 at 0:57
  • 2
    \$\begingroup\$ "In the picture, one N would make the bottom face a 2" isn't the bottom face already a 2? \$\endgroup\$
    – paulvs
    Dec 13 '15 at 15:21
  • \$\begingroup\$ @Sp3000, edited, the net should be provided but your code should be able to handle no movement commands. \$\endgroup\$
    – Riker
    Dec 13 '15 at 17:40
  • 1
    \$\begingroup\$ You measure the size of your dice in bytes? \$\endgroup\$
    – Cyoce
    Dec 13 '15 at 17:56
  • \$\begingroup\$ @Cyoce No, just the text on each face. So the face with 🍄 on it would be 4 bytes. For this challenge, I want to be able to fit the code you write on my dice. To do that, I need small code. \$\endgroup\$
    – Riker
    Dec 13 '15 at 18:10

CJam, 43 40 37 34 bytes

Thanks to Dennis for helping me save 6 bytes.


Test it here.


lW%    e# Read the first line and reverse it.
S/     e# Split it around spaces.
$      e# Sort it. This puts the faces in order [B E N S T W].
1f=    e# Select the second character from each face, which is the number.
q      e# Read the remainder of the input (the instructions).
{      e# For each instruction...
  i8%  e#   Convert the character (NWSE) to an integer and take modulo 8.
       e#   Use that to (cyclically) index this string and convert *that* character
       e#   to an integer.
  \    e#   Swap with the list of faces.
  m!   e#   Generate all permutations of the faces.
  =    e#   Select the permutation corresponding to the above integer.
}/     e# At the end of the loop, the bottom face will be the first character.
c      e# Convert the string to a character, which discards everything but the bottom face.

As for how the mapping of instruction characters to permutations works, here is a handy table:

   i   8%  5%  ""=   i   [0 1 2 3 4 5]m!=

N  78   6   1   Ĕ   276  [2 1 4 0 3 5]
W  87   7   2   ɠ   608  [5 0 2 3 1 4]
S  83   3   3   Ƃ   386  [3 1 0 4 2 5]
E  69   5   0   É   201  [1 4 2 3 5 0]

I've included the 5% column because that is what the cyclic indexing into the string does implicitly. For the four permutations we can see that each of them leaves two (opposite) sides untouched and cyclically permutes the other four.

  • \$\begingroup\$ How do you represent the permutations as those Unicode characters? How does Ĕ represent the permutation of N [2 1 4 0 3 5]? I've been staring at it for hours. \$\endgroup\$
    – paulvs
    Dec 13 '15 at 17:59
  • 1
    \$\begingroup\$ @paulvs The character code of Ĕ is 276. 6e! gives you a list of all 720 permutations of [0 1 2 3 4 5]. And 276 happens to be the index of [2 1 4 0 3 5] in that list. \$\endgroup\$ Dec 13 '15 at 18:02
  • \$\begingroup\$ I wished more people would have answered, but you were the shortest. Congrats. \$\endgroup\$
    – Riker
    Dec 25 '15 at 21:59

Perl, 166 158 154 144 139 135 134 132 116 bytes

includes +1 for -p


With comments:

                                    # example input: "NS, 1S 2B 3E 4W 5T 6N"
s/(\d)(.)/$h{$2}=$1/eg;             # construct %h ( S=>1, B=>2, E=>3, W=>4, B=>2, N=>6 )

                                    # = Transformations =
$N='NTSB',                          # N becomes T, T becomes S, S becomes B, B becomes N

map {                               # iterate the moves "NS"
    @h{ @l } =                      # LHS: bulk-assign new values; @l defined in RHS
      @h{                           # RHS: init @l, transform
          (@l=$$_=~/./g)            # get transform, put ('N','T','S','B') in @l for LHS
          [1..3,0]                  # construct a rotated slice for RHS
} /\w/g;                            # match the movements in list context

$_=$h{B}                            # assign the bottom face to output.

Input file:

, 1S 2B 3E 4W 5T 6N
N, 1S 2B 3E 4W 5T 6N
NS, 1S 2B 3E 4W 5T 6N
NWS, 1S 2B 3E 4W 5T 6N
NWSNWS, 1S 2B 3E 4W 5T 6N
NWSS, 1S 2B 3E 4W 5T 6N
NNNNNN, 1S 2B 3E 4W 5T 6N
SNWEEWS, 1N 2T 3E 4W 5B 6S
SNEEWS, 1N 2T 3W 4S 5B 6E

Run with

perl -p dice.pl < input.txt

Output: 262223564

  • update 158 Using $N, $S, $E, $W global variables instead of %t = {N=>, S=>, E=>, $W=>} saves 8 bytes.

  • update 154 Since the requirement is that the program output a number, not printing the newline print "$h{B}\n" saves 4 bytes: print $h{B}.

  • update 144 Save 10 bytes by doing

    ($s)=/^(\w+),/;            s/(\d)(.)/$h{$2}=$1/eg;

    instead of

    ($s,@i)=split /,? |\n/;    %h=reverse map{split//}@i;
  • update 139 Move the regex for the command to the end to eliminate a variable, saving 6 bytes.

  • update 135 Save 4 bytes on @l[0..3,0] instead of @l[1..3],$l[0].

  • update 134 Save 1 byte by using assignment @l=split//,$$_ as value.

  • update 132 Save 2 bytes by doing /^\w+/ && $& instead of /^(\w+)/ && $1.

  • update 129 Save 3 bytes by using -p instead of -n and assigning $_ for print.

  • update 116 Save 13 bytes by rewriting split//, /^\w+/ && $& into /^\w+/g.


Python 2, 204 bytes

Thought it was time to respond to my own question.

def x(p,m):
    d={p[3*i-2]:i for i in range(1,7)}
    for j in m:n=2if j in'NE'else-2;x='BSTN'if j in'NS'else'BETW';d[x[0]],d[x[1]],d[x[2]],d[x[3]]=d[x[1+n]],d[x[(2+n)%4]],d[x[(3+n)%4]],d[x[0+n]]
    print d['B']

Not very short, but works.

Run as:

x('1B 2T 3N 4S 5W 6E','SNEEWS')
#Output: 4

Edit: Counted bytes wrong. Now longer. :(

  • \$\begingroup\$ BTW, thanks xnor for the python macro. \$\endgroup\$
    – Riker
    Dec 14 '15 at 4:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.