I've written an implementation of the "famous" Mars Rover simulation, (another question on this) whose problem statement is this:
The first line of input is the upper-right coordinates of the plateau, the lower-left coordinates are assumed to be 0,0.
The rest of the input is information pertaining to the rovers that have been deployed. Each rover has two lines of input. The first line gives the rover's position, and the second line is a series of instructions telling the rover how to explore the plateau.
The position is made up of two integers and a letter separated by spaces, corresponding to the x and y co-ordinates and the rover's orientation.
Each rover will be finished sequentially, which means that the second rover won't start to move until the first one has finished moving.
Output:
The output for each rover should be its final co-ordinates and heading.
Test Input:
5 5 1 2 N LMLMLMLMM 3 3 E MMRMMRMRRM
Expected Output:
1 3 N 5 1 E
This is my working solution:
dirs =: 'NESW'
input =. _4]\ 2 }. '' cut (' ',LF) charsub fread '~/Desktop/marsrover.txt'
NB. State transitions are the directions rotated forward and backwards
st =. 0,."1~ (] ,. 1 |. ] ,. _2 |. ]) i. # dirs
NB. R = 1, L = 2, anything else = 0
a =. ('R'=a.) + (2 * 'L'=a.)
NB. Run the state machine against the input, initial facing on left
facing =: dirs {~ 4 {"1 ] ;:~ 5 ; st; a; 0 _1 , _1 ,~ dirs i. [
NB. Detect motion in each direction
moves =: ] #~ 1 - 'M' i. [
simulate =: monad define "1
'x0 y0 dir commands' =. y
pos =. ". x0, ' ', y0
f =. dir facing commands
dest =. pos + (+/ (dirs i. commands moves f) { 4 2 $ 0 1 1 0 0 _1 _1 0)
(": dest), ' ', {: f
)
echo simulate input
exit ''
My plan for this program was basically this:
- Run a state machine with the current facing against the input to figure out what the facing is at the moment of each command. This is what
facing
calculates. - Get the facing corresponding to each
M
command - Take the sum of "move" vectors to get the total change in coordinates. N = 0 1, so three moves with facing N will be the sum of 0 1 + 0 1 + 0 1 = 0 3.
- The solution is the sum of the total change in coordinates with the initial coordinate, plus the final facing state.
What I'd like review for, is to find out if this code is idiomatic J, if there are more direct ways to do what I'm trying to do here, and especially in the simulate
verb, if there are better ways to handle taking apart the input and passing it through the other verbs. I am happy that I figured out how to use sequential machine, but overall this solution feels a bit gassy to me. But I haven't found another implementation to compare to.