An ant needs help moving around specific faces on a 6 sided die in order. Write a program or function which, given a series of numbers between 1 and 6, outputs the shortest set of instructions to travel to those faces around the die.
The face with the 1 is towards you, the 2 is on top, and the 3 is to your right. (This is a left-handed die.) Faces 1 and 6, 2 and 5, and 3 and 4 are opposite. The faces are laid out like this:
5
6
2
413
The ant always begins on the 1 face, facing up, towards the 2.
To get to the 2 face, it needs to go Forward. To get to the 5 face from there, it would need to go Forward twice. To get to the 3 face from there, it would need to turn Right, then Forward. To get back to the 5, it would need to move Backward. (Moving backward is shorter than turning twice then moving forward).
Thus, given an input of 2,5,3,5 the instructions required are F,FF,RF,B. Notice how the instructions are grouped for each destination. (F,BB,RF,B is another correct solution, as are F,FF,LB,F and F,BB,LB,F. The sample data prefers F over B when both are possible.)
Input
A series of 1 or more integers in the range 1-6, in any format you like. You can use 0-5 if you prefer. Each face will be different from the previous, and the first input face is not 1 (since the ant starts at 1). (If you want, you can have the input always include an extra 1 at the start, as the starting face.)
Output
A series of delimited sets of instructions, where each instruction is one of R (right), L (left), F (forward), B (backward). You can output these in any format you like, so long as there is a clear grouping. So [['F'], ['F','F'],['R','F']] would be acceptable, as well as F;F F;R F or f\nff\nrf. Lowercase is fine. Extra whitespace is fine. Using characters other than /[FRLBfrlb]/ to indicate directions is not allowed.
Challenge
This is code golf. Standard rules apply.
Sample data
2535=>F FF RF B616=>FF FF FF35421=>RF RF F F RF654321=>FF F LF FF B LF2131415161=>F B RF B B F RF B FF FF
Related questions involving ants and cubes
4 Answers 4
JavaScript (Node.js), 104 bytes
x=>x.map(g=t=>t-H?([H,F]=t-F?t+R-7&&t-R?[7-F,H,'B']:[H,R,'R',R=7-F]:[F,7-H,'F'])[2]+g(t):'',H=1,F=2,R=3)
Never turn left. It's useless.
-
\$\begingroup\$ Wow, very impressive! \$\endgroup\$Steve Bennett– Steve Bennett2025年04月04日 07:34:10 +00:00Commented Apr 4 at 7:34
Charcoal, 57 bytes
≔⭆6⊕ιηFS«§⪪"&↓⎇\`ï≧ξ,8" ⌕ηι→≔⭆§⪪"←⧴◨¡C·κ<B✂9S!i¿" ⌕ηι§ηIκη
Try it online! Link is to verbose version of code. Explanation:
≔⭆6⊕ιη
Start with the six digits.
FS«
Loop over the input.
§⪪"&↓⎇\`ï≧ξ,8" ⌕ηι→
Output the move that will bring the ant to the desired digit.
≔⭆§⪪"←⧴◨¡C·κ<B✂9S!i¿" ⌕ηι§ηIκη
Update the ant's position and direction.
As far as I can tell, local optimal is also global optimal. In any given position, F and B can only allow you to visit four of the six digits; you'll need to turn to reach the other two, which you might as well do immediately as the best that taking an extra F or B can do is to save you a single turn later on. For example, 32 might as well be RF LF as FRF B is the same length. But just in case you aren't convinced, I wrote a program that definitively finds the globally optimal solution, although it is 50% longer, and a lot slower of course:
⊞υ⟦S⭆6⊕ιω⟧FυFEE∧¬iFBR⟦§ι0⭆§⪪")⊟}↓&≕G*"6λ§§ι1Iμ+§ι2κ⟧⎇⌕§ι0§§κ1¦0κEκ§⟦Φμπμ+μ ⟧ν¿⌊κ⊞υκ⊟κ
Try it online! Link is to verbose version of code. Outputs a trailing space. Explanation:
⊞υ⟦S⭆6⊕ιω⟧Fυ
Start a breadth-first search with the input as the faces left to visit, the current die position, and the moves taken.
FEE∧¬iFBR⟦§ι0⭆§⪪")⊟}↓&≕G*"6λ§§ι1Iμ+§ι2κ⟧⎇⌕§ι0§§κ1¦0κEκ§⟦Φμπμ+μ ⟧ν
If no solution has been found, then for each of the moves FBR (L isn't needed, as you can just flip all of the letters starting at that L, e.g. FF F LF can be FF F RB), calculate the new die position, and then remove the next face if possible.
¿⌊κ⊞υκ⊟κ
If this is not a solution then add it to the search list otherwise print the moves taken.
-
\$\begingroup\$ Hmm... I don't follow the logic in the closing paragraph.
32are neighboring faces, so one move should be enough. Did you mean an implicit1as in132? For32, the routes for the four orientations would seem to beF,B,RFandLF|RB. I cannot see howRF LFandF RF Bwould be the same length? \$\endgroup\$doubleunary– doubleunary2025年04月04日 13:07:33 +00:00Commented Apr 4 at 13:07 -
\$\begingroup\$ @doubleunary I meant
32as an input, so yes, the1is implicit. \$\endgroup\$Neil– Neil2025年04月04日 14:59:51 +00:00Commented Apr 4 at 14:59
Ruby, 102 bytes
->i{x,y,z=1,2,3
i.map{|j|k=s="";(x,y=y,7-x;k+=?F;k[3]&&(y,z,s,k=z,7-y,?R,""))while x!=j;s+=k[2]??B:k}}
6 bytes saved with help from l4m2.
Ruby, 108 bytes
->i{x,y,z=1,2,3
i.map{|j|j-=j/4*7;k=s="";z*z==j*j&&(y,z,s=z,-y,?R);(x,y=y,-x;k+=?F)while x!=j;s+=k[2]??B:k}}
A function taking an array of face numbers and returning an array of strings. Will also handle repeat numbers in the input - If the current face is in the input, an empty string is returned.
The dice is represented by the vector x,y,z which initially contains 1,2,3 containing the top, front and right sides. If the desired face is to the left or right, we rotate about the x axis y,z=z,-y (always to the right.) Then we rotate forward about the z axis x,y=y,-x until the desired face is on top. If the number of rotations is more than 2 we output B otherwise we output the relevant number of Fs.
Faces j other than 1,2,3 are represented by j-7 and are therefore -3,-2,-1 for 4,5,6. A vector with x=-1 means that the 1 face is on the bottom so the 6 face represented by -1 is on top.
There are some similarities between l4m2 's code and mine but I'm not sure if they are using the same approach.
commented code
->i{x,y,z=1,2,3 #set up vector x,y,z with start position
i.map{|j| #iterate j through elements in input array i
j-=j/4*7 #if j=4,5,6 subtract 7 to convert to -3,-2,-1
k=s="" #setup 2 empty strings: s for right turns, k for forward
z*z==j*j&&(y,z,s=z,-y,?R) #if desired face is right or left (magnitude of j and z is equal) rotate right and s="R"
(x,y=y,-x;k+=?F)while x!=j #rotate forward until desired face on top. Add "F" to k each time
s+=k[2]??B:k} #final value is s (either "R" or "") with k appended. If k has more than 2 F's append "B" instead.
} #return with the value returned by .map (the final values of each iteration.)
-
\$\begingroup\$ Is cost of
j-=j/4*7lower than treating them as 4-6? \$\endgroup\$l4m2– l4m22025年04月07日 00:33:12 +00:00Commented Apr 7 at 0:33 -
\$\begingroup\$ @l4m2 Thanks, your comment is timely, because I was thinking about losing the initial check to see if the desired cell was on the side and simply go forward 4 times (and if that fails rotate right.) Doing that alone would have increased my code by 1 byte. I'm not sure how I would have done that initial check without
j-=j/4, but making both changes together saves 6 bytes. On another note, your answer is impressive but I'm still not sure exactly how your code works. \$\endgroup\$Level River St– Level River St2025年04月07日 18:57:34 +00:00Commented Apr 7 at 18:57
Jelly, 38 bytes
×ばつtṭ‘Ä©8ịðiị(BgDݤṃ"FRB"ṄȧƲị®œ?8ðƒ®
A monadic Link that accepts a list of face numbers (not starting with 1 and without any equal neighbours) and prints to stdout as a side effect (and yields a list of numbers, which may be ignored).
How?
Permute some permutation indices :)
×ばつtṭ‘Ä©8ịðiị(BgDݤṃ"FRB"ṄȧƲị®œ?8ðƒ® - Link: list of integers, Faces×ばつtṭ‘ - code page indices -> [1,224,132,17,116,224]
Ä - cumulative sums -> [1,225,357,374,490,714]
= the permutation indices of:
[no-op, F, RF, RB, B, FF] from [1,2,3,4,5,6]
© - ...and copy that to the register
8ị - Faces indexed into {that} -> P
ð ðƒ® - starting with the register, reduce P by - f(Current, PValue):
i - 1-index of {PValue} in {Current}
Ʋ - last four links as a monad - SideEffect(X=that):
ị - 1-index {X} into:
¤ - nilad followed by links as a nilad
(Bg - 17604
D - to decimal -> [1,7,6,0,4]
Ż - prefix with a zero -> [0,1,7,6,0,4]
ṃ"FRB" - convert to base three with digits 120 as FRB
Ṅ - print {that} to stdout and yield {that}
ȧ - {that} logical AND {X} -> X
ị® - 1-index {X} into the register
œ?8 - permutation of {Current} at {that} index -> Next
FForBB). \$\endgroup\$