|
1 | 1 | (ns robot-simulator) |
2 | 2 |
|
3 | | -(def directions [:north :east :south :west]) |
4 | | - |
5 | | -(defn robot [coordinates bearing] |
6 | | - {:coordinates coordinates :bearing bearing}) |
7 | | - |
8 | | -(defn turn [bearing direction-list] |
9 | | - (let [dir-stream (drop-while #(not (= bearing %1)) (cycle direction-list))] |
10 | | - (nth dir-stream 1))) |
11 | | - |
12 | | -(defn turn-right [bearing] |
13 | | - (turn bearing directions)) |
14 | | - |
15 | | -(defn turn-left [bearing] |
16 | | - (turn bearing (reverse directions))) |
17 | | - |
18 | | -(defn advance [coordinates bearing] |
19 | | - (let [x (:x coordinates) |
20 | | - y (:y coordinates)] |
21 | | - (cond |
22 | | - (= :north bearing) {:x x :y (inc y)} |
23 | | - (= :south bearing) {:x x :y (dec y)} |
24 | | - (= :east bearing) {:x (inc x) :y y} |
25 | | - (= :west bearing) {:x (dec x) :y y}))) |
26 | | - |
27 | | -(defn simulate [instructions current-state] |
28 | | - (loop [instructions instructions |
29 | | - current-state current-state] |
30 | | - (let [instruction (first instructions) |
31 | | - remainder (rest instructions) |
32 | | - coordinates (:coordinates current-state) |
33 | | - bearing (:bearing current-state) |
34 | | - next-state (cond |
35 | | - (= \L instruction) |
36 | | - (robot coordinates (turn-left bearing)) |
37 | | - (= \R instruction) |
38 | | - (robot coordinates (turn-right bearing)) |
39 | | - :else |
40 | | - (robot (advance coordinates bearing) bearing))] |
41 | | - (if (seq remainder) |
42 | | - (recur remainder next-state) |
43 | | - next-state)))) |
44 | | - |
| 3 | +(defn robot |
| 4 | + [coordinates direction] |
| 5 | + {:coordinates coordinates :bearing direction}) |
| 6 | + |
| 7 | +(def turn-right-> |
| 8 | + {:east :south |
| 9 | + :south :west |
| 10 | + :west :north |
| 11 | + :north :east}) |
| 12 | + |
| 13 | +(def turn-left-> |
| 14 | + {:east :north |
| 15 | + :north :west |
| 16 | + :west :south |
| 17 | + :south :east}) |
| 18 | + |
| 19 | +(def move-direction->update-vector |
| 20 | + {:north [:y inc] |
| 21 | + :east [:x inc] |
| 22 | + :west [:x dec] |
| 23 | + :south [:y dec]}) |
| 24 | + |
| 25 | +(defn turn-robot-left |
| 26 | + [robot] |
| 27 | + (update robot :bearing turn-left->)) |
| 28 | + |
| 29 | +(defn turn-robot-right |
| 30 | + [robot] |
| 31 | + (update robot :bearing turn-right->)) |
| 32 | + |
| 33 | +(defn advance-robot |
| 34 | + [robot] |
| 35 | + (let [[k f] (-> :bearing robot move-direction->update-vector)] |
| 36 | + (update-in robot [:coordinates k] f))) |
| 37 | + |
| 38 | +(defn execute-instruction |
| 39 | + [robot instruction] |
| 40 | + (case instruction |
| 41 | + \L (turn-robot-left robot) |
| 42 | + \R (turn-robot-right robot) |
| 43 | + \A (advance-robot robot))) |
| 44 | + |
| 45 | +(defn simulate |
| 46 | + [instructions robot] |
| 47 | + (reduce execute-instruction robot instructions)) |
0 commit comments