# Let's move the Mars rover!

## Summary

The task is to navigate the Mars rover and tell its final coordinates and direction.

# Input:

## First input:

First your program must take the input which will be in the following format:

``````[X-Coordinate],[Y-Coordinate],[Direction]
``````

The direction must be: `N` or `S` or `E` or `W` (Starting letters of North, South, West, East)

Example: `10,20,N` ( x = 10, y = 20, direction = N(North))

## Second input:

The second input consists of series of `R`, `L`, `M` for right, left and move respectively.

For `R` and `L` (right and left) the direction of rover must change accordingly.

For `M` the rover must move 1 unit ahead in the direction which it was before moving.

Rules for calculating coordinates:

``````N = Y + 1
E = X + 1
S = Y - 1
W = X - 1
``````

## Output:

The final coordinates and the current direction of the rover.

Example:

``````Enter initial data:      1,2,N

Enter the instructions:  MRMLM

Output:                  2,4,N
``````

The coordinates can be any integer and can be negative.

All the standard loopholes aren't allowed. If providing demo on sites like http://ideone.com etc. is possible, then please do so, so that I can verify :)

This is a popularity contest so be creative!

Following others' advice, I decide to make this a .

-
Are there limits to the coordinates? – Teun Pronk Jun 19 '14 at 14:32
This might be more interesting as code-golf instead of popularity-contest. What kind of bonus is given for the use of ideone? – Kyle Kanos Jun 19 '14 at 14:33
@KyleKanos I saw people using it, so just used. Rephrased it ;) – Amit Joki Jun 19 '14 at 14:35
You know, if you're experiencing negative feedback on your challenges, try running them through the sandbox first. – Martin Büttner Jun 19 '14 at 14:49
@Geobits thanks. Stated explicitly. – Amit Joki Jun 19 '14 at 15:09

## Ruby ≥ 2.0, 101

``````E,N,W,S=*0..3
x,y,i=eval"a="+gets
gets.bytes{|c|x+=c%2*1i**i=i+1-c&3}
\$><<[(x+y.i).rect,"NWSE"[i]]*?,
``````

This solution can be tested here: https://ideone.com/C4PLdE

Note that the solution linked on ideone is one character longer (`1.i` instead of `1i` in line 3). The reason for this is that ideone only supports Ruby 1.9, which doesn't allow the short-hand syntax for complex literals.

-
waiting to see it golf further :) – Amit Joki Jun 19 '14 at 17:07
You can replace `x,y,i=eval"[#{gets}]"` with `eval"x,y,i="+gets` to save some chars. – voidpigeon Jun 19 '14 at 17:11
@voidpigeon: I'm not sure that actually works due to `eval`'s scoping rules: `ruby -e 'eval"x=1";p x'` throws a `NameError` for `x` at `p x`. It does work when using constants (`eval"X,Y,I="+gets`), but since I modify `i`, this would require an additional `i=I` to prevent warnings about redefining a constant. But maybe we're talking about different Ruby versions? – Ventero Jun 19 '14 at 17:14
@Ventero You're right. I tested it in irb and it gave me the proper array as output so I assumed it worked. I really like the eval approach though. – voidpigeon Jun 19 '14 at 17:19
@voidpigeon Ah, you're right, that actually allows a slightly different optimization: `x,y,i=eval"*a="+gets`. Thanks! – Ventero Jun 19 '14 at 17:21

# Javascript (ES6) 145141 127

Edit: Removed the need for a translation array using method from edc65's C solution

``````[x,y,d]=(p=prompt)(s='NESW').split(','),[...p(d=s.search(d))].map(c=>c!='M'?(d+=c>'M'||3,d%=4):d%2?x-=d-2:y-=d-1),p([x,y,s[d]])
``````

Ungolfed/Commented:

``````s='NESW' // initialize variable for direction mapping
[x,y,d]=prompt().split(',') // get first input, split by commas, map to variables x,y,d
d=s.search(d) // get numeric value for direction
[...prompt()].map(c=> // get second input, map a function to every character in it
c!='M'? // if char is not M
(d+=c>'M'||3, // increment d by 1 if char greater than M, otherwise 3
d%=4) // modulo by 4 to wrap direction
: // else
d%2? // if odd direction
x-=d-2 // move x position
: // else
y-=d-1 // move y position
)
prompt([x,y,s[d]]) // output result
``````
-
you can do this?! [a,b,c] = x.split(...) – edc65 Jun 19 '14 at 17:10
@edc65 Yup! Destructuring Assignment – nderscore Jun 19 '14 at 17:17
Have a look at my C answer. maybe the g array is not needed – edc65 Jun 20 '14 at 5:37
Thanks @edc65 that saves a lot of bytes! – nderscore Jun 20 '14 at 14:48

# Java - 327

``````class R{public static void main(String[]a){char c,e=a[2].charAt(0),z[]={78,69,83,87};Integer x=Integer.valueOf(a[0]),y=x.valueOf(a[1]),d=e<70?1:e==83?2:e>86?3:0,i=0;for(;i<a[3].length();d=c>81?(d+1)%4:c<77?(d+3)%4:d){c=a[3].charAt(i++);if(c==77){x=d==1?x+1:d>2?x-1:x;y=d<1?y+1:d==2?y+1:y;}}System.out.print(x+","+y+","+z[d]);}}
``````

With whitespace:

``````class R{
public static void main(String[]a){
char c,e=a[2].charAt(0),z[]={78,69,83,87};
Integer x=Integer.valueOf(a[0]),y=x.valueOf(a[1]),d=e<70?1:e==83?2:e>86?3:0,i=0;
for(;i<a[3].length();d=c>81?(d+1)%4:c<77?(d+3)%4:d){
c=a[3].charAt(i++);
if(c==77){
x=d==1?x+1:d>2?x-1:x;
y=d<1?y+1:d==2?y+1:y;
}
}
System.out.print(x+","+y+","+z[d]);
}
}
``````

As usual with Java, about half of this is just parsing the input and forming the output. The logic is pretty straightforward.

-

# Javascript (E6) 175

Edit Fixed bug, possibly out of range return value for d

139 Logic, 36 I/O

``````F=(x,y,d,m,D='NESW')=>(d=D.search(d),[...m].map(s=>({M:_=>(y-=[-1,0,1,0][d],x-=[0,-1,0,1][d]),R:_=>d+=1,L:_=>d+=3}[s](),d%=4)),[x,y,D[d]]);
p=prompt,p(F(...p().split(','),p()))
``````

Basic ungolfed

``````function F(x,y,d,m) // In golf code use arrow sintax instead of 'function'
{
var D='NESW';
d = D.search(d); // map from letters to offset position 0..3
var driver = { // driver object, each function map one of  command letters M,R,L
M: function() {
y -= [-1, 0, 1, 0][d]; // subtract to be sure to have a numeric and not string result
x -= [0, -1, 0, 1][d]; // subtract to be sure to have a numeric and not string result
},
R: function() {
d += 1;
},
L: function() {
d += 3; // with modulo 4 will be like -= 1
}
}
m = [...m]; // string to array, to use iteration function
m.forEach(  // array scan, in golf versione use map do nearly the same and is shorter
function (s) {
driver[s](); // call driver function
d = d % 4;   // restrict value to modulo 4
}
);  // in golf version, use comma separated expression to avoid 'return'
return [x,y, D[d]] // return last status
}
``````

Test Test in javascript console in Firefox. It's simpler to test the function F avoiding the popups.

``````F(1,2,'N','MRMLM')
``````

Output

``````[ 2, 4, "N" ]
``````
-
Nice, this looks a lot like my solution. – nderscore Jun 19 '14 at 16:39

# C 164 180 186

Edit Fixed input format and removed strchr
Edit Removed offset array, calc using bits

``````p,x,y;main(){char c,d,l[100];scanf("%d,%d,%c%s",&x,&y,&d,l);for(d=d<83?d&1:d>>2&1|2;c=l[p++];d&=3)c-77?d+=c+1:d&1?x+=d-2:(y+=1-d);printf("%d %d %c",x,y,"NESW"[d]);}
``````

Ungolfed

``````p, x, y;
main()
{
char c, d, l[100];
scanf("%d,%d,%c%s",&x,&y,&d,l);
for (d = d<'S'?d&1:d>>2&1|2; c = l[p++]; d &= 3)
c-'M'
? d += c+1
: d & 1 ? x+=d-2 : (y+=1-d);
printf("%d %d %c", x, y, "NESW"[d]);
}
/*
M 77
R 82 0101 0010 R&3+1==3
L 76 0100 1100 L&3+1==1
*/
``````
-

# Python 2.7 - 197 192 bytes

``````q='NESW';x,y,d=raw_input().split(',');x=int(x);y=int(y);d=q.find(d);v={0:'y+',1:'x+',2:'y-',3:'x-'}
for c in raw_input():exec['d+','d-',v[d]]['RL'.find(c)]+'=1;d=d%4'
print`x`+','+`y`+','+q[d]
``````

I'm actually super proud of this one.

Explanation

First, let's clean up this mess. I used semicolons instead of line breaks in a lot of places because I think it makes me cool. Here it is normally (this is still 197 bytes, it hasn't been ungolfed at all). Yes, there's still a semicolon, but that one actually saves a byte.

``````q='NESW'
x,y,d=raw_input().split(',')
x=int(x)
y=int(y)
d=q.find(d)
v={0:'y+',1:'x+',2:'y-',3:'x-'}
for c in raw_input():m=v[d];exec['d+','d-',m]['RL'.find(c)]+'=1;d=d%4'
print`x`+','+`y`+','+q[d]
``````

Let's begin!

``````q='NESW'
``````

First we define `q` as the string `'NESW'`. We use it twice later, and `len("q='NESW';qq") < len("'NESW''NESW'")`.

``````x,y,d=raw_input().split(',')
``````

Here we split the first line of inpupt at each comma. Our x coord is stored in `x`, y in `y`, and the first letter of our direction in `d`.

``````x=int(x)
y=int(y)
``````

Then we just make the coords ints. (I was shocked that I couldn't think of a better way to convert two strings to ints. I tried `x,y=map(int,(x,y))` but that turns out to be longer.)

``````d=q.find(d)
``````

This converts our direction to an integer. 0 is north, 1 is east, 2 is south and 3 is west.

``````v={0:'y+',1:'x+',2:'y-',3:'x-'}
``````

This is where the fun starts.

When we go north, Y increases by 1. So this dictionary takes 0 and gives the string `'y+'`, for "increase y". It gives similar results for other directions: y or x followed by + or -.

We'll come back to this.

``````for c in raw_input():
m=v[d]
exec['d+','d-',m]['RL'.find(c)]+'=1;d=d%4'
``````

I've gone to the liberty of ungolfing this one slightly.

For each character in the second line of input, we do two things. First, we set the variable `m` to whatever our dictionary from before gives us for our current direction. There's no reason we need this to happen every time, but it's easier than just making it happen when we need it.

Next, we create a list with three elements: `'d+'`, `'d-'`, and `m`. EDITOR'S NOTE: I think I can get away with not using the variable `m` at all. I think I can just put `v[d]` in the list directly. That'll save me a couple bytes if it works, but I don't feel like testing it until I'm done this explanation so y'all can deal. (Yep, it worked.)

We look for the current character of the input in the string 'RL'. `str.find` returns -1 if it doesn't find the character, so this converts an R to a 0, an L to a 1 and anything else to -1. Of course, the only other input we can have is M, but it's less characters to make it work for everything.

We use that number as the index for the list we created. Python list indices start at the end if they're negative, so we get the first element if the input is R, the second if it's L, and the last if it's M. For for convenience's sake, I'm about to assume that we're facing north, but a similar principle applies for other directions.

The possible values we're working with are `'d+'` for R, `'d-'` for L and `'y+'` for M. Then, we attach `'=1;d=d%4'` to the end of each one. That means our possible values are...

``````d+=1;d=d%4
d-=1;d=d%4
y+=1;d=d%4
``````

That's valid python code! That's valid python code that does exactly what we want to do for each of those input characters! (The `d=d%4` part just keeps our directions sane. Again, don't need to do it every time, but it's less characters.)

All we have to do is execute the code we get for each character, print it out (converting our direction back to a string), and we're done!

-

# C, 148 150151

``````p,x[2];main(){char c,d,l[99],*j="%d,%d,%c%s";scanf(j,x,x+1,&d,l);for(d=d%8%5;c=l[p++];d-=c%23)x[d&1]-=c%2*~-(d&2);printf(j,*x,x[1],"ENWS"[d&3],"");}
``````

A tweak of @edc65's solution to use my ASCII value abuse approach.

Specifically:

• `d%8%5` maps the characters `ENWS` to `0,1,2,3` respectively
• `c%23` turns `L` into `7`, `M` into `8` and `R` into 13. Because `d` (the direction variable) is always used mod 4, this effectively makes `L` add -1 mod 4, `M` add 0 mod 4, and `R` add 1 mod 4.
• `d&1` is 1 for `NS` and 0 for `EW` directions.
• `d&2` is 2 for `WS` and 0 for `NE` directions.
• `~-(d&2)` is 1 for `WS` and -1 for `NE` directions.
• `c%2` is 1 for `M` and 0 for `LR`.
-
Why 23, and what is `c%(2*(1-(d&2)))` – tolos Jun 20 '14 at 16:17
@tolos: Added some explanation. Also shortened by 2 characters :) – nneonneo Jun 20 '14 at 16:46

# Python 3 (with turtle graphics), 251 199 bytes

Wise pythonistas, please be gentle, for this is my first ever attempt at a program written in your fine language.

# Turtles on Mars!

``````from turtle import*
p="NESW"
mode("logo")
x,y,d=input().split(',')
setx(int(x))
sety(int(y))
seth(p.find(d)*90)
for c in input():fd(1)if c=="M"else[lt,rt][c>'L'](90)
``````

This challenge maps quite naturally to logo-style turtle graphics, for which python has an import, of course.

Reads input from two lines from STDIN.

Output:

``````\$ { echo 1,2,N; echo MRMLM; } | python ./rover.py
(2.00,4.00) N
\$
``````

What I especially like about this program is it actually graphically displays the rover's path. Add `exitonclick()` to the end of the program so the graphical output persists until user click:

I'm pretty sure this can be golfed significantly more - any suggestions welcome! I'm making this CW, because I hope the community can golf it some more.

Changes:

• s is now a list, inlined.
• Used ternary for body of for loop.
• Inlined n, removed unnecessary slice.
• Removed unnecessary space in import statement.
• Removed import string to use builtin string method
• Switched to Python 3 to shorten raw_input
-
@isaacg Thanks - nice golfing! – Digital Trauma Jun 20 '14 at 19:28

# GolfScript, 116 98 88 84 71

``````~'NESW':^@?:&;{4%[{&(4%:&;}{&[{)}{\)\}{(}{\(\}]=~}{&)4%:&;}]=~}/]`&^1/=
``````

This should get the coordinates and the instructions as arguments the following way:`1 2 'N' 'MRMLM'`. The arguments are made into a string and are pushed into the stack.

If you want to test this online, go to web golfscript and paste a semicolon followed with a string with the arguments (e.g. `;"1 2 'N' 'MRMLM'"`) before the code (here's a link with an example).

Examples of output:

``````1 2 'N' 'MRMLM'                    -> [2 4]N
5 6 'E' 'MMLMRMRRMMML'             -> [5 7]S
1 2 'N' 'MMMMRLMRLMMRMRMLMRMRMMRM' -> [1 8]N
``````

## My Previous Attempts

84 chars:

``````~:i;'NESW':k\?:d;{i(\:i;4%[{d(4%:d;}{d[{)}{\)\}{(}{\(\}]=~}{d)4%:d;}]=~i}do]`d k 1/=
``````

88 chars:

``````~:i;'NESW':k\?:d;{i(\:i;'MRL'?[{d[{)}{\)\}{(}{\(\}]=~}{d)4%:d;}{d(4%:d;}]=~i}do]`d k 1/=
``````

98 chars:

`````` ~1/:i;:d;{'NESW'd?}:k;{k[{)}{\)\}{(}{\(\}]=~}:M;{k'ESWN'1/=:d;}:R;{k'WNES'1/=:d;}:L;{i(\:i;~i}do d
``````

116 chars:

``````[~])\~"NESW":k 1/:d?{d(1/+:d;}:f*:y;:x;{("MRL"?[{k d 0=?[{y):y}{x):x}{y(:y}{x(:x}]=~;}{f}{d)1/\+:d;}]=~.}do x y d 0=
``````
-
btw: the old versions of the post are stored so you can see howthey were in the past (just click on the "Edited xxx ago" link) – masterX244 Jun 22 '14 at 9:01

# Delphi (819)

When I started it was not yet. Will edit later.

Can't find a compiler online though.

``````uses SysUtils;type TDirection = (dNorth, dEast, dSouth, dWest);var x,y:int64;dir:TDirection;input:string;c:char;function gd(C:Char):TDirection;var o:integer;begin o:=ord(dir);if C='L'then o:=o-1else if c='R'then o:=o+1else if c='N'then exit(dNorth)else if c='E'then exit(dNorth)else if c='S'then exit(dNorth)else if c='W'then exit(dNorth);if o>3 then exit(dNorth);if o<0 then exit(dWest);exit(TDirection(o))end;function DirLetter:string;begin if dir=dNorth then exit('N');if dir=dEast then exit('E');if dir=dSouth then exit('S');if dir=dWest then exit('W');end;begin Readln(x,y,input);dir := gd(Input[1]);readln(Input);Input:=UpperCase(Input);for C in Input do begin if C<>'M' then dir:=gd(C)else case dir of dNorth:y:=y+1;dEast:x:=x+1;dSouth:y:=y-1;dWest:x:=x-1;end;end;writeln(Format('%d,%d,%s',[x,y,DirLetter]));end.
``````

Ungolfed

``````uses
SysUtils;
type
TDirection = (dNorth, dEast, dSouth, dWest);

var
x,y:int64;
dir:TDirection;
input:string;
c:char;

function gd(C:Char):TDirection;
var
o:integer;
begin
o:=ord(dir);
if C='L' then
o:=o-1
else if c='R' then
o:=o+1
else if c='N' then
exit(dNorth)
else if c='E' then
exit(dNorth)
else if c='S' then
exit(dNorth)
else if c='W' then
exit(dNorth);

if o>3 then exit(dNorth);
if o<0 then exit(dWest);
exit(TDirection(o))
end;
function DirLetter:string;
begin
if dir=dNorth then exit('N');
if dir=dEast then exit('E');
if dir=dSouth then exit('S');
if dir=dWest then exit('W');
end;
begin
dir := gd(Input[1]);
Input:=UpperCase(Input);
for C in Input do
begin
if C<>'M' then
dir:=gd(C)
else
case dir of
dNorth:y:=y+1;
dEast:x:=x+1;
dSouth:y:=y-1;
dWest:x:=x-1;
end;
end;
writeln(Format('%d,%d,%s',[x,y,DirLetter]));
end.
``````
-
may be ideone and the option is Pascal? – Amit Joki Jun 19 '14 at 15:15
"When I started it was not code-golf yet." Is that your excuse for coding in Delphi? ;) – Martin Büttner Jun 19 '14 at 15:16
What's up with the spaces around `=`? Why are they needed? Also, the variable names seem way too long to me – Jan Dvorak Jun 19 '14 at 17:20
@m.buettner ssshh, dont spill the beans :P – Teun Pronk Jun 20 '14 at 6:45
@JanDvorak Like I said, it wasn't tagged as code-golf – Teun Pronk Jun 20 '14 at 6:46

# Javascript (353)

This is my first real attempt at code golf, seems to work at least!

``````var xx=[0,1,0,-1];var yy=[1,0,-1,0];var d=["N","E","S","W"];var e=0;var x,y=0;function sa(p){q=p.split(",");x=+q[0];y=+q[1];e=+d.indexOf(q[2]);}function sb(t){var g=t.split(",");for(var u=0;u<g.length;u++){if(g[u]=='R'){e++;if(e>3)e=0;}if(g[u]=='L'){e--;if(e<0)e=3;}if(g[u]=='M'){x+=+xx[e];y+=+yy[e];}}alert(x+","+y+","+d[e]);}sa(prompt());sb(prompt());
``````
-
I can see unnecessarily long variables names ;). Also, in code golf nobody cares about proper variable scoping, so drop those `var `s. – Martin Büttner Jun 19 '14 at 15:41

## Python (263)

``````input =  raw_input("Initial: ")
input2 = raw_input("Command: ")

position = [int(input[0]), int(input[2]), input[4]]

bearings = "NESW"
turns = {"L" : -1, "M": 0, "R" : 1}
move = {"N" : [0, 1], "E" : [1, 0], "S" : [0, -1], "W" : [-1, 0]}

for c in input2:
turn = turns[c];
if (turn == 0):
position[0] += move[position[2]][0]
position[1] += move[position[2]][1]
else:
position[2] = bearings[(bearings.index(position[2]) + turn)%4]

print "Output: ", ','.join((str(s) for s in position))
``````

There must be a more elegant way of doing this also, it doesn't need the branch after the else.

http://ideone.com/eD0FwD

The input is awful, I wanted to do it with `split(',')` but came across casting issues between the ints and strings. Ideally I also wanted to add the old position with the moving position... oh it's code-golf now. Oh well whatever, I'll leave it here, might give inspiration. Other ideas I had were using modulo 4 of the direction after mapping the initial bearing to an index. Also merging the turns and move arrays to one since none of the keys collide.

even so, shortening variable names and removing spaces it's 263:

``````i=raw_input()
j=raw_input()
p=[int(i[0]),int(i[2]),i[4]]
b="NESW"
m={"N":[0,1],"E":[1,0],"S":[0,-1],"W":[-1,0],"L":-1,"M":0,"R":1}
for c in j:
if (m[c]==0):
p[0]+=m[p[2]][0]
p[1]+=m[p[2]][1]
p[2] = b[(b.index(p[2])+m[c])%4]
print ','.join(str(s) for s in p)
``````
-

# C - 350

Save as `rover.c`:

``````#include<stdio.h>
#include<string.h>
#include<math.h>
int main(){char c,*C="NWSE-WN";float x,y,d,k=M_PI/2;scanf("%f,%f,%c",&x,&y,&c);d=(strchr(C,c)-C)*k;do{switch(getchar()){case'R':d+=k;break;case'L':d-=k;break;case'M':x+=sin(d);y+=cos(d);break;case EOF:printf("%g,%g,%c\n",x,y,C[(int)(sin(d)+2*cos(d)+4.5)]);}}while(!feof(stdin));return 0;}
``````

Compile:

``````gcc -o rover rover.c -lm
``````

Sample run:

``````\$ echo 1,2,N MRMLM | ./rover
2,4,N
``````

Ideone

Ungolfed:

``````#include <stdio.h>
#include <string.h>
#include <math.h>

int main()
{
/* String is used for input and output, pi/2 == 90 degrees */
char c, *C = "NWSE-WN";
float x, y, d, k = M_PI/2;

/* Get starting parameters */
scanf("%f,%f,%c", &x, &y, &c);

/* Convert the direction NWSE into radians */
d = (strchr(C, c) - C) * k;

/* Process each character */
do
{
/* Recognize R(ight), L(eft), M(ove) or EOF */
switch (getchar())
{
case 'R':
/* Turn right 90 degrees */
d += k;
break;

case 'L':
/* Turn left 90 degrees */
d -= k;
break;

case 'M':
/* Advance 1 unit in the direction specified */
x += sin(d);
y += cos(d);
break;

case EOF:
/* Output - formula is specially crafted so that S,E,W,N
map to indices 2,3,5,6 to reuse part of string */
printf("%g,%g,%c\n", x, y, C[(int)(sin(d) + 2*cos(d) + 4.5)]);
}
}
while (!feof(stdin));

return 0;
}
``````
-

``````import Text.Parsec
import Text.Parsec.String
n='N'
s='S'
e='E'
w='W'
d(x,y,c)'M'|c==n=(x,y+1,c)|c==s=(x,y-1,c)|c==e=(x+1,y,c)|c==w=(x-1,y,c)
d(x,y,c)e=(x,y,i c e)
i 'N''R'=e
i 'N''L'=w
i 'S''R'=w
i 'S''L'=e
i 'E''R'=s
i 'E''L'=n
i 'W''R'=n
i 'W''L'=s
f=many digit
g=char ','
o=oneOf
``````

Tested with :

``````\$ printf "1,2,N\nMRMLM" | ./rv
Right (2,4,'N')
``````
-
Hah hah! Great to see Haskell so far behind the pack, for a change :D – GreenAsJade Jun 20 '14 at 10:41
`f=many digit` MUCH LOL - SUCH WOW – tomsmeding Jun 22 '14 at 6:31
Splitting the input and using `read` multiple times took more characters to do than using parsec... – gxtaillon Jun 22 '14 at 12:14

# Bash+coreutils, 159 bytes

``````t()(tr \$2 0-3 \$1<<<\$d)
d=`t '' NESW`
for s in `fold -1`;{
[ \$s = M ]&&((`t yxyx;t ++-`=1))||d=\$[(d`tr LR -+<<<\$s`1+4)%4]
}
echo \$x,\$y,`t NESW`
``````

Input is read from 2 lines of STDIN.

Output:

``````\$ { echo 1,2,N; echo MRMLM; } | ./rover.sh
2,4,N
\$
``````
-

## PowerShell, 170167 166

``````[int]\$x,[int]\$y,\$e,\$m="\$input"-split'\W'
\$d='NESW'.indexof(\$e)
switch([char[]]\$m){'R'{\$d++}'L'{\$d--}'M'{iex(-split'\$y++ \$x++ \$y-- \$x--')[\$d%4]}}
"\$x,\$y,"+'NESW'[\$d%4]
``````

Can't seem to golf this down further, which is a bit embarrassing. But all the obvious hacks don't really work here.

I can't `iex` the input because a) `N`, `S`, `E` and `W` would have to be functions for that to work (or I'd need to prefix that with `\$` and b) `1,2,N` would have to parse the `N` in expression mode, not being able to run a command.

The `switch` seems to be the shortest way of doing the movement. Hash table with script blocks or strings isn't shorter either and for every other way apart from the `switch` I'd have the overhead of the explicit loop.

I can't get rid of the `IndexOf` because a pipeline with `?` is longer, still.

I also can't get rid of the explicit types in the initial declaration because I have mixed types there, so a simple `|%{+\$_}` doesn't help and every other option is longer.

Sometimes I hate input handling in PowerShell.

-

# Python, 135 137138

``````S,W,N,E=0,1,2,3;a,b,d=input();v=[b,a]
for c in map(ord,raw_input()):d+=c%23;v[d&1]+=c%2*~-(d&2)
print'%d,%d,%s'%(v[1],v[0],'SWNE'[d&3])
``````

Abuses the ASCII values of `L`, `M` and `R` to avoid using any conditional statements.

Try it in ideone.

-

# C 300218203 188

Try with http://www.compileonline.com/compile_c_online.php pass arguments to stdin, e.g. `1,2,N MRMLM`, which are space separated. First is the initial conditions following by movement.

Edit: Huge improvement from automatic scanf formatting -- thanks to Yimin Rong for the idea.
Edit: No need to convert final direction, just index into string.
Edit: (alright I'm done now.) Shoved everything into a for loop; replaced equality check with XOR; replaced `if...else` with ternary. Replaced scanf and printf format strings with same variable.

``````x,y,p,d,c;main(){char b[9],*f="%d,%d,%c %s";scanf(f,&x,&y,&p,b);for(p=(p&16)>>3|p>>2&p&1;d=b[c++];d^77?p=((d&4)/2)+p+1&3:(y+=!p?1:p==2?-1:0,x+=p&1?p&2?-1:1:0));printf(f,x,y,"NESW"[p],"");}
``````

ungolfed:

``````// uncomment to fix implicit declaration of printf
//#include <stdio.h>

// change to local definition to remove type definition warning
x,y,p,d,c;

main()
{
//int x,y,p,d,c;
char b[9],*f="%d,%d,%c %s";

// Parse input. Thank you scanf.
scanf(f,&x,&y,&p,b);

// convert N,E,S,W into 0,1,2,3. NESW is chosen to be able
// to rotate clockwise and counter-clockwise.
// Look at ASCII and try to find bit fields to map to 00,01,10,11
// This can be done using the 4th ASCII bit for the largest bit,
// and bitwise ANDing the 0th and 2nd ASCII bit
// N 0x4e = 0100 1110 -> xxx0 x1x0 -> program 0
// E 0x45 = 0100 0101 -> xxx0 x1x1 -> program 1
// S 0x53 = 0101 0011 -> xxx1 x0x1 -> program 2
// W 0x57 = 0101 0111 -> xxx1 x1x1 -> program 3
// This is slightly better than the ternary approach:
//     p = p&78?0:p&69?1:p&83?2:3;
for(p=(p&16)>>3|p>>2&p&1;

d=b[c++];

// Movement explanation:
//
//     if(d!=77)
d^77

// Rotate position orientation
// R = 0x52 = 0101 0010
// L = 0x4c = 0100 1100
// Rotating right is the same as adding one to the position orientation,
// modulus four; rotating left is the same as subtracting one, is the
// same as adding three modulus four. Use the 2nd bit of the input
// to decide if this is a plus one or plus three operation.
// Can drop the parenethses by replacing %4 with &3
? p = ((d&4)/2)+p+1&3

// Else it must be an 'M'
//
//     y += !p ? 1 : (p == 2 ? -1 : 0),
//
// The only condition for !p to be true is if p==0, which is North.
// Otherwise if p==2, direction is South.
// Comma separated so both expressions are executed without using
// brackets.
//
//     x += p&1 ? (p&2 ? -1 : 1) : 0;
//
// East and West, being encoded as 1 and 3 uniquely share the first
// (least) bit. Then the only check that needs to happen is whether
// this is a 1 or a 3, which happens with p&2.
:(
y += !p ? 1 : p==2 ? -1 : 0,
x += p&1 ? p&2 ? -1 : 1 : 0
)
);

printf(f,x,y,"NESW"[p],"");

// need a return type
//return 0;
}
``````

Lessons learned:

• Know the tools. `scanf` does automatic type conversion, no need to call `atoi` or anything. For future reference, stdin will be much shorter than trying to parse command line arguments.
• Never use `if...else`. Ternary is much shorter.
• Modulo `2^x` is the same as bitwise AND `2^x - 1` for positive integers.
• Don't forget about indexing into strings (`1["asdf"] = "asdf"[1]`).
• When calling scanf and printf with the same input and output, the format string can be saved and reused between the two.
• Global variables are initialized to zero.
-
Just 8 chars for the move commands? – edc65 Jun 19 '14 at 20:31

# Python 2.7, 170 149

``````N,E,S,W=q='NESW'
x,y,d=input()
d=q.find(d)
for c in raw_input():exec['d+','d-','yx'[d%2]+'+-'[d/2]]['RL'.find(c)]+'=1;d%=4'
print`x`+','+`y`+','+q[d]
``````

Things I changed from the original:

Aliased raw_input, changed the v[d] dictionary, which should have been a list anyways, to some string selection, used `%=`.

Edit: used tuple unpacking and eval(raw_input())==input() to save 21 characters.

Heavily borrowed from @undergroundmonorail, but with lots of improvements.

-
Nice! I like this a lot. – undergroundmonorail Jun 20 '14 at 3:13

# Bash/SHELF, 243 235

"SHEll goLF" is a golfing library for Bash which provides a few useful aliases. This is a valid answer as the library existed and was on GitHub before the challenge was posted.

Sorry, I can't get this to work on ideone.

## How to run

This takes the initial position (separated by commas as specified; this adds a lot of characters to the code) as its first argument, and the instructions on standard input.

``````source shelf.sh #you must load SHELF first
source rover.sh 1,2,N<<<MRMLM #now run the script via source so it has access to SHELF
``````

## Sample output

``````2,4,N
``````

## Code

``````o=\$1
D(){ o=`y NESW \$1<<<\$o`;}
for x in `Y . '& '`;{
d \$x R&&D ESWN
d \$x L&&D WNES
d \$x M&&z=(`y , \ <<<\$o`)&&case \${z[2]} in N) z[1]=\$[z[1]+1];;S) z[1]=\$[z[1]-1];;W) z[0]=\$[z[0]-1];;E) z[0]=\$[z[0]+1];;esac&&o=`P \${z[@]}|y \  ,`
}
p \$o
``````

## Explanation

`d` is for comparison; it returns 0 if its two arguments are equal and 1 otherwise, it can then have other commands chained onto it with `&&` and `||`.

`y` is like `tr` (but done through `sed`).

`Y` is like `sed 's/.../.../g'` for its two arguments.

`P` is `echo -e -n`; `p` is just `echo -e`.

``````o=\$1 #save first argument to variable
D(){ o=`y NESW \$1<<<\$o`;} #define an alias to turn R or L
for x in `Y . '& '`;{ #add a space after every character on stdin and loop for each one
d \$x R&&D ESWN #turn R using alias
d \$x L&&D WNES #turn L using alias
``````

The next bit is profoundly ugly, with about 145 chars on one line. If the current command is M, turn the commas in \$o into spaces, convert to array and save to \$z. Then, do a switch...case block for the last element of \$z (the direction the rover is pointing. Change coordinates accordingly, then convert \$z back into a comma-separated string and save to \$o.

``````d \$x M&&z=(`y , \ <<<\$o`)&&case \${z[2]} in N) z[1]=\$[z[1]+1];;S) z[1]=\$[z[1]-1];;W) z[0]=\$[z[0]-1];;E) z[0]=\$[z[0]+1];;esac&&o=`P \${z[@]}|y \  ,`
} #end loop
p \$o #print output
``````
-
Shouldn't the sourcing of `shelf.sh` be part of the solution instead? Like you'd have to `require` certain packages in Ruby or `import` them in Python as well if you need them. – Joey Jun 20 '14 at 12:55
@Joey good point, but I don't think people `import` PYG when writing a Python program with it, or Rebmu (AFAIK) when writing a Rebol program with it – professorfish Jun 20 '14 at 14:26

``````data D=W|S|E|N deriving(Show,Read,Enum)
``````

I wasn't sure how flexible the input and output string format was, so I made sure it looked exactly like the example (minus the prompts, of course), but that added a lot of extra characters. Ideone link

-

# PHP - 224

Well, I gave it a try.

``````\$n=explode(",",\$argv[1]);\$d=(\$e=\$n[2])==W?0:(\$e==N?1:(\$e==E?2:3));for(;\$i<strlen(\$n[3]);)if((\$o=\$n[3][\$i++])==M)\$n[\$d%2]+=\$d>1?-1:1;else\$d=\$o==R?(\$d+1)%4:(\$d==0?3:\$d-1);echo"{\$n[0]},{\$n[1]},".(\$d==1?N:(\$d==2?E:(\$d==3?S:W)));
``````

Input in STDIN, e.g.:

``````\$ php mars_rover.php 1,2,N,MMMRRRRRMM
-1,5,E
\$ php mars_rover.php 1,2,N,MMMMRLMRLMMRMRMLMRMRMMRM
1,8,N
\$ php mars_rover.php 3,-2,W,MMMMLM
7,-3,S
``````
-

# Python3 (288)

Implementation using heavy use of ternary ifs.

``````m=['N','E','S','W']
cords=[int(n) for n in input().split()] + [input()] #Convert first inputs to integers and retrieve third
for n in input(): #Get instructions
if n=='M':
i=[1,0][cords[2] in m[1:3]] #See if vertical or horizontal
j=[-1,1][cords[2] in m[0:2]] #See if negative or positive
cords[i]+=j
else:
i=[-1,1][n=='R'] #Translate turn to numerals
cords[2]=m[m.index(cords[2])+i] #Change direction relative to current orientation
print(cords)
``````

Omitting the obvious input grumbles, giving the direction strings intrinsic values may have benefited the script size. However, the approach here is perfectly functional (so I believe)

-
Welcome to PPCG. This is code-golf, so the shortest answer wins. You can start by making your variable names one char long. – Digital Trauma Jun 19 '14 at 20:48

# Python 3 (143)

``````I=input
a,b,D=I().split(',')
w='ENWS'
d=w.find(D)
x=int(a)+int(b)*1j
for c in I():x+=(c=='M')*1j**d;d+='ML'.find(c)
print(x.real,x.imag,w[d%4])
``````

http://ideone.com/wYvt7J

We use Python's built-in complex number type to store the pair of coordinates. The direction is computed by taking the imaginary unit `1j` to the power of `d`, which stores the direction mod 4. Rotating is done by incrementing or decrementing `d`. The expression `'ML'.find(c)` gives the amount we want to change `d`: `1` for `L`, `0` for `M`, and `-1` (the default for not found) for `R`.

Python doesn't have a short way to convert a complex number to a tuple, so we have to make costly calls to `.real` and `.imag`.

-