Instantly share code, notes, and snippets.

# ghoseb/rover.clj Last active Jun 9, 2016

Mars rover problem solved in Clojure.
 (ns mars.rover) ;; A squad of robotic rovers are to be landed by NASA on a plateau on ;; Mars. ;; This plateau, which is curiously rectangular, must be navigated by the ;; rovers so that their on-board cameras can get a complete view of the ;; surrounding terrain to send back to Earth. ;; A rover's position and location is represented by a combination of x and ;; y co-ordinates and a letter representing one of the four cardinal ;; compass points. The plateau is divided up into a grid to simplify ;; navigation. An example position might be 0, 0, N, which means the rover ;; is in the bottom left corner and facing North. ;; In order to control a rover , NASA sends a simple string of letters. The ;; possible letters are "L", "R" and "M". "L" and "R" makes the rover spin ;; 90 degrees left or right respectively, without moving from its current ;; spot. "M" means move forward one grid point, and maintain the same ;; heading. ;; Assume that the square directly North from (x, y) is (x, y+1). ;; INPUT: ;; 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. ;; INPUT AND OUTPUT ;; Test Input: ;; 5 5 ;; 1 2 N ;; LMLMLMLMM ;; 3 3 E ;; MMRMMRMRRM ;; Expected Output: ;; 1 3 N ;; 5 1 E (def ^:private directions (vec "NEWS")) (def ^:private shifts [[0 1] [1 0] [0 -1] [-1 0]]) (def ^:private instructions (zipmap "RLM" [(fn [x y d] "Turn right." [x y (mod (inc d) 4)]) (fn [x y d] "Turn left." [x y (mod (+ (dec d) 4) 4)]) (fn [x y d] "Go straight." [(+ x (first (nth shifts d))) (+ y (second (nth shifts d))) d])])) (defn- position [coll item] "Find the position of item in coll." (first (for [[idx x] (map-indexed vector coll) :when (= x item)] idx))) (defn- process-command [init-pos instruction] "Take an initial state and process a new instruction." (apply (instructions instruction) init-pos)) (defn- process-commands* [init-pos instructions] "Take an initial state and process a bunch of instructions." (reduce process-command init-pos instructions)) (defn process-commands [[x y d] instructions] "Take an initial state and process a bunch of instructions." (if-let [direction (position directions d)] (let [[x y d] (process-commands* [x y direction] instructions)] [x y (directions d)]))) ;;; Examples ;; (process-commands [1 2 \N] "LMLMLMLMM") -> [1 3 \N] ;; (process-commands [3 3 \E] "MMRMMRMRRM") -> [5 1 \E]

### gja commented Nov 6, 2013

 I think you meant s/find-in/position

### anildigital commented Jan 3, 2014

 Get error for #89 clojure.lang.Compiler\$CompilerException: java.lang.RuntimeException: Unable to resolve symbol: find-in in this context, compiling:(NO_SOURCE_PATH:3:22)
Owner Author

### ghoseb commented Jun 9, 2016

 @anildigital It should be fixed now. There was a typo.