Skip to content

Instantly share code, notes, and snippets.

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

What would you like to do?
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).
;; 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.
;; The output for each rover should be its final co-ordinates and heading.
;; Test Input:
;; 5 5
;; 1 2 N
;; 3 3 E
;; 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)))
(defn- position [coll item]
"Find the position of item in coll."
(for [[idx x] (map-indexed vector coll) :when (= x item)]
(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]

This comment has been minimized.

Copy link

commented Nov 6, 2013

I think you meant s/find-in/position


This comment has been minimized.

Copy link

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)


This comment has been minimized.

Copy link
Owner Author

commented Jun 9, 2016

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.