Skip to content

Instantly share code, notes, and snippets.

@davidporter-id-au
Last active January 11, 2017 12:05
Show Gist options
  • Save davidporter-id-au/5a6e9f4b661da3aea1bd09d57ef439a9 to your computer and use it in GitHub Desktop.
Save davidporter-id-au/5a6e9f4b661da3aea1bd09d57ef439a9 to your computer and use it in GitHub Desktop.
(def direction-map ["R3", "R1", "R4", "L4", "R3", "R1", "R1", "L3", "L5", "L5", "L3", "R1", "R4", "L2", "L1", "R3", "L3", "R2", "R1", "R1", "L5", "L2", "L1", "R2", "L4", "R1", "L2", "L4", "R2", "R2", "L2", "L4", "L3", "R1", "R4", "R3", "L1", "R1", "L5", "R4", "L2", "R185", "L2", "R4", "R49", "L3", "L4", "R5", "R1", "R1", "L1", "L1", "R2", "L1", "L4", "R4", "R5", "R4", "L3", "L5", "R1", "R71", "L1", "R1", "R186", "L5", "L2", "R5", "R4", "R1", "L5", "L2", "R3", "R2", "R5", "R5", "R4", "R1", "R4", "R2", "L1", "R4", "L1", "L4", "L5", "L4", "R4", "R5", "R1", "L2", "L4", "L1", "L5", "L3", "L5", "R2", "L5", "R4", "L4", "R3", "R3", "R1", "R4", "L1", "L2", "R2", "L1", "R4", "R2", "R2", "R5", "R2", "R5", "L1", "R1", "L4", "R5", "R4", "R2", "R4", "L5", "R3", "R2", "R5", "R3", "L3", "L5", "L4", "L3", "L2", "L2", "R3", "R2", "L1", "L1", "L5", "R1", "L3", "R3", "R4", "R5", "L3", "L5", "R1", "L3", "L5", "L5", "L2", "R1", "L3", "L1", "L3", "R4", "L1", "R3", "L2", "L2", "R3", "R3", "R4", "R4", "R1", "L4", "R1", "L5"])
;(def direction-map ["R8", "R4", "R4", "R8"])
(def directions-list [:N :E :S :W])
(def start-state {:d :N :l {:x 0 :y 0} :v []})
(defn rotate [rel-direction facing-currently]
(let [
dir-to-int (fn [d] (.indexOf directions-list d))
curr-dir-facing-int (dir-to-int facing-currently)
int-to-dir (fn [i] (nth directions-list (Math/abs (mod i 4))))
]
(cond
(= rel-direction "R") (int-to-dir (+ curr-dir-facing-int 1))
(= rel-direction "L") (int-to-dir (- curr-dir-facing-int 1))
:else (throw (Exception. (str "An invalid instruction was received: " rel-direction))))))
(defn append-to-visit-log [state loc]
(assoc-in state [:v] (conj (:v state) loc)))
(defn abs-decrement-delta [delta]
"Send delta towards zero, or, use logic because I can't use simple mathematics"
(cond
(> delta 0) (dec delta)
(< delta 0) (inc delta)
:else 0))
(defn inch-y [delta current-location state direction]
(let [
inch-direction (if (< delta 0) -1 1)
updated-state (-> (append-to-visit-log state current-location)
(assoc :l current-location)
(assoc :d direction))
next-location (assoc-in current-location [:y] (+ (:y current-location) inch-direction))
]
(if (= 0 delta)
(assoc state :l current-location)
;else, keep inching recursively, adding to the map of entries visited
(inch-y (abs-decrement-delta delta) next-location updated-state direction))))
(defn inch-x [delta current-location state direction]
(let [
updated-state (-> (append-to-visit-log state current-location)
(assoc :l current-location)
(assoc :d direction))
inch-direction (if (< delta 0) -1 1)
next-location (assoc-in current-location [:x] (+ (:x current-location) inch-direction))
]
(if (= 0 delta)
(assoc state :l current-location)
(inch-x (abs-decrement-delta delta) next-location updated-state direction))))
(defn move [direction distance state]
"Determines the new location and direction based on current state and direction"
(cond
(= direction :N) (inch-y distance (:l state) state direction)
(= direction :S) (inch-y (* -1 distance) (:l state) state direction)
(= direction :E) (inch-x distance (:l state) state direction)
(= direction :W) (inch-x (* -1 distance) (:l state) state direction)
:else (throw (Exception. (str "An invalid instruction was received: " direction)))
))
(defn follow-directions [directions state]
(reduce (fn [curr-state r]
(let [direction-to-travel (rotate (subs r 0 1) (get-in curr-state [:d])) distance (. Integer parseInt (subs r 1))]
(move direction-to-travel distance curr-state)))
state
directions))
(defn distance-between-two-points [a b]
"calculates the taxi-cab distance between two points"
(+ (Math/abs (- (get-in a [:y]) (get-in b [:y])))
(Math/abs (- (get-in a [:x]) (get-in b [:x])))))
(def first-double-visit (let [
sequence-of-visits (:v (follow-directions direction-map start-state))
frequencies (frequencies sequence-of-visits)
]
(first (filter (fn [el] (> (get-in frequencies [el]) 1 )) sequence-of-visits))))
(distance-between-two-points first-double-visit (:l start-state))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment