Rolling the Dice

16

2

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.

Input

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.

Output

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.

Rɪᴋᴇʀ

Posted 2015-12-12T15:32:56.780

Reputation: 7 410

2Does the first test case with (nothing) -> 2 mean that no net is provided, or should there be a net there somewhere? – Sp3000 – 2015-12-13T00:57:09.547

2"In the picture, one N would make the bottom face a 2" isn't the bottom face already a 2? – paulvs – 2015-12-13T15:21:44.003

@Sp3000, edited, the net should be provided but your code should be able to handle no movement commands. – Rɪᴋᴇʀ – 2015-12-13T17:40:45.097

1You measure the size of your dice in bytes? – Cyoce – 2015-12-13T17:56:03.010

@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. – Rɪᴋᴇʀ – 2015-12-13T18:10:25.083

The last test case SNEEWS, 1N 2T 3W 4S 5B 6E isn't a valid die: opposite sides should sum to 7. – Kenney – 2015-12-13T18:38:03.637

@Kenney I know, but it shouldn't make a difference for your program. My dice are weird, as noted in the above comments. – Rɪᴋᴇʀ – 2015-12-13T18:39:38.630

Answers

8

CJam, 43 40 37 34 bytes

Thanks to Dennis for helping me save 6 bytes.

lW%3/$1f=q{i8%"ÉĔɠƂ!"=i\m!=}/c

Test it here.

Explanation

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.
  "ÉĔɠƂ!"=i
       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.

Martin Ender

Posted 2015-12-12T15:32:56.780

Reputation: 184 808

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. – paulvs – 2015-12-13T17:59:53.800

1@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. – Martin Ender – 2015-12-13T18:02:38.320

I wished more people would have answered, but you were the shortest. Congrats. – Rɪᴋᴇʀ – 2015-12-25T21:59:13.093

5

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

includes +1 for -p

s/(\d)(.)/$h{$2}=$1/eg;$N='NTSB',$S='STNB',$E='ETWB',$W='WTEB';map{@h{@l}=@h{(@l=$$_=~/./g)[1..3,0]}}/\w/g;$_=$h{B}

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
$S='STNB',
$E='ETWB',
$W='WTEB';

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.

Kenney

Posted 2015-12-12T15:32:56.780

Reputation: 946

Crossed out 44 is still regular 44. – Rɪᴋᴇʀ – 2015-12-18T18:18:43.057

4

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. :(

Rɪᴋᴇʀ

Posted 2015-12-12T15:32:56.780

Reputation: 7 410

BTW, thanks xnor for the python macro. – Rɪᴋᴇʀ – 2015-12-14T04:23:11.310