Efficient Robot Movement
Retina, 103 74 71 bytes
<
>>>
+`(>(\^*>){3})\^
^$1
+`\^(>\^*>)\^
$1
>>(\^*)>(\^+)
<$2<$1
<?>*$
Try it online! Link includes test cases. Explanation:
<
>>>
Turn left turns into triple right turns.
+`(>(\^*>){3})\^
^$1
Reduce all turns modulo 4.
+`\^(>\^*>)\^
$1
Cancel out movements in opposite directions.
>>(\^*)>(\^+)
<$2<$1
Turn a triple right turn back into a left turn. This also handles the case of >>^>^
which needs to become <^<^
.
<?>*$
Delete unnecessary trailing turns.
Mathematica, 135 bytes
{a="^"~Table~Ramp@#&;a@#,s=If[#2>0,">","<"],a@Abs@#2,If[#<0,s,""],a@-#}<>""&@@ReIm[j=0;i=1;Switch[#,">",i*=I,"<",i/=I,"^",j+=i]&/@#;j]&
Takes a List
of strings as input.
Explanation
j=0;i=1
Set j
to 0, and set i
to 1.
/@#
For each character in input...
Switch[#,">",i*=I,"<",i/=I,"^",j+=i]
If the character is >
, multiply i
by the imaginary unit. If the character is >
, divide i
by the imaginary unit. If the character is ^
, add i
to j
.
ReIm[ ... ;j]
Take the real and imaginary parts of j
. This gives the Cartesian coordinate of the robot.
... &@@
Apply the following to this result:
a="^"~Table~Ramp@#&;
Set a
to a function that generates a string with (input)
or 0
character ^
s, whichever is larger.
{ ... }
A List
consisting of...
a@#
a
applied to the first input (real part of j
)
s=If[#2>0,">","<"]
If the second input (imaginary part of j
) is larger than 0
, >
. Otherwise, <
. Set s
to the resulting character.
a@Abs@#2
a
applied to the absolute value of the second input.
If[#<0,s,""]
If the first input is less than 0, s
. Otherwise, empty string.
a@-#
Apply a
to the input times negative one.
... <>""
Join the strings.
Mathematica 119 Bytes
JungHwan's final position to path code was shorter than mine, so using that. I think there is probably an even shorter way to do this...
I use the built-in AnglePath
function to decide the final position. I also define the symbols L, F, and R for "<", "^" and ">", to save a few quote characters.
L={0,Pi/2};R=-L;F={1,0};{a="F"~Table~Ramp@#&;a@#,s=If[#2>0,"L","R"],a@Abs@#2,If[#<0,s,""],a@-#}<>""&@@Last@AnglePath@#&
Usage:
%@{R,F,L,L,F,F,R,F,F}
Output:
FFLF