Created
March 29, 2012 04:37
-
-
Save mikebridge/2233330 to your computer and use it in GitHub Desktop.
Codelesson Clojure Assignment 4
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns codelesson.assignment-4 | |
(:require [clojure.string :as str])) | |
(defn rotate-left [current-dir] | |
{:pre [(char? current-dir)]} | |
((apply hash-map (seq "NWWSSEEN")) current-dir)) | |
(defn rotate-right [current-dir] | |
{:pre [(char? current-dir)]} | |
((apply hash-map (seq "NEESSWWN")) current-dir)) | |
(defn rotate [rover f] | |
(assoc rover :orientation (f (:orientation rover)))) | |
(defn delta-xy [direction] | |
{:pre [(char? direction)]} | |
({\N [0 1] \E [1 0] \S [0 -1] \W [-1 0]} direction)) | |
(defn new-point [& vec] | |
(apply map + vec)) | |
(defn move [rover] | |
(assoc rover :position | |
(new-point (:position rover) (delta-xy (:orientation rover))))) | |
(defn command [cmd] | |
{:pre [(char? cmd)]} | |
(cond | |
(= cmd \M) (fn [rover] (move rover)) | |
(= cmd \R) (fn [rover] (rotate rover rotate-right)) | |
(= cmd \L) (fn [rover] (rotate rover rotate-left)))) | |
(defn rover-hash [position-coords orientation] | |
{:position (vec position-coords) :orientation orientation}) | |
(defn movement-functions [movement-commands] | |
(map #(command %1) movement-commands)) | |
;; collisions result in a no-op. | |
(defn apply-movement [rover plateau-size move-fn] | |
{:pre [(map? rover) (vector? plateau-size) (fn? move-fn)]} | |
(let [new-pos (move-fn rover) | |
maxx (first plateau-size) | |
maxy (second plateau-size) | |
x (first (:position new-pos)) | |
y (second (:position new-pos))] | |
(if (or (< x 0) | |
(> x maxx) | |
(< y 0) | |
(> y maxy)) | |
rover | |
new-pos))) | |
(defn rove- | |
[plateau-size start-pos commands] | |
{:pre [(vector? plateau-size) (vector? start-pos) (string? commands)]} | |
(let [move-fns (movement-functions commands) | |
rover (rover-hash (take 2 start-pos) (start-pos 2))] | |
(reduce #(apply-movement %1 plateau-size %2) (cons rover move-fns)))) | |
(defn str-to-vec [s] | |
(read-string (str "[" s "]"))) | |
(defn char-if-sym [s] | |
(if (symbol? s) | |
(first (str s)) | |
s)) | |
(defn convert-position [pos] | |
{:pre [(string? pos)]} | |
(vec (map char-if-sym (str-to-vec pos)))) | |
(defn rover-to-string [rover] | |
(str (first (:position rover)) " " (second (:position rover)) " " (:orientation rover))) | |
(defn positions-to-string [position-list] | |
(clojure.string/join "\n" (map rover-to-string position-list))) | |
(defn rove [in] | |
{:pre [(string? in)]} | |
(let [lines (clojure.string/split-lines in) | |
plateau-size (str-to-vec (first lines)) | |
pos-and-command-pairs (partition 2 (rest lines))] | |
(positions-to-string | |
(map #(rove- plateau-size | |
(convert-position (first %)) | |
(first (rest %))) pos-and-command-pairs)))) |
Author
mikebridge
commented
Mar 29, 2012
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment