Skip to content

Instantly share code, notes, and snippets.

@daemianmack
Created March 23, 2012 01:37
Show Gist options
  • Save daemianmack/2166073 to your computer and use it in GitHub Desktop.
Save daemianmack/2166073 to your computer and use it in GitHub Desktop.
My mars-rover solution
;; 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
;; NOTE: For the first cut, there is no need to handle collisions or
;; boundary checks (as in, assume that the input is happy path). For
;; added credit, handle collisions and boundary checks in any way you
;; see fit.
(use '[clojure.string :only (split)])
(defmulti handle-move (fn [x y move facing] [(str move) facing]))
(defmethod handle-move ["M" "N"] [x y move facing] [x (+ y 1) facing])
(defmethod handle-move ["M" "E"] [x y move facing] [(+ x 1) y facing])
(defmethod handle-move ["M" "S"] [x y move facing] [x (- y 1) facing])
(defmethod handle-move ["M" "W"] [x y move facing] [(- x 1) y facing])
(defmethod handle-move ["R" "N"] [x y move facing] [x y "E"])
(defmethod handle-move ["R" "E"] [x y move facing] [x y "S"])
(defmethod handle-move ["R" "S"] [x y move facing] [x y "W"])
(defmethod handle-move ["R" "W"] [x y move facing] [x y "N"])
(defmethod handle-move ["L" "N"] [x y move facing] [x y "W"])
(defmethod handle-move ["L" "E"] [x y move facing] [x y "N"])
(defmethod handle-move ["L" "S"] [x y move facing] [x y "E"])
(defmethod handle-move ["L" "W"] [x y move facing] [x y "S"])
(defn do-move [instruction]
(loop [x (instruction :x)
y (instruction :y)
facing (instruction :facing)
moves (instruction :moves)]
(if (empty? moves)
(println x y facing)
(let [[x y facing] (handle-move x y (first moves) facing)]
(recur x y facing (rest moves))))))
(defn parse-args [input]
"Parse new-line-delimited input into 1) grid size, and 2) infinite series
of a) x and b) y starting coordinates, c) initial facing direction, and
d) series of turns/moves."
(let [lines (split input #"\n")
grid (first lines) ; TODO
cmd-pairs (partition 2 (rest lines))]
(for [pair cmd-pairs]
(let [xyf (split (nth pair 0) #"\s")
x (Integer/parseInt (nth xyf 0))
y (Integer/parseInt (nth xyf 1))
facing (nth xyf 2)
moves (nth pair 1)]
{:x x :y y :facing facing :moves moves}))))
(def input "5 5
1 2 N
LMLMLMLMM
3 3 E
MMRMMRMRRM")
(map do-move (parse-args input))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment