-
-
Save srazzaque/7be0482c606506a8b860 to your computer and use it in GitHub Desktop.
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 trains | |
(:import java.time.LocalDateTime | |
java.time.format.DateTimeFormatter)) | |
(def trips | |
;; Each trip is a uni-directional trip. | |
[{:id 0, | |
:stops [{:stop "Wynyard" | |
:time "2015-07-15T18:47"} | |
{:stop "Town Hall" | |
:time "2015-07-15T18:49"} | |
{:stop "Central" | |
:time "2015-07-15T18:53"} | |
{:stop "Redfern" | |
:time "2015-07-15T18:55"}]} | |
{:id 1, | |
:stops [{:stop "Wynyard" | |
:time "2015-07-15T18:48"} | |
{:stop "Town Hall" | |
:time "2015-07-15T18:50"} | |
{:stop "Redfern" | |
:time "2015-07-15T18:54"} | |
{:stop "Redfern" | |
:time "2015-07-15T18:56"}]}]) | |
(defn- parse-date | |
[date-str] | |
(LocalDateTime/parse date-str DateTimeFormatter/ISO_DATE_TIME)) | |
(defn- is-date-after? | |
[date1 date2] | |
(.isAfter (parse-date date1) | |
(parse-date date2))) | |
(defn goes-to? | |
"Returns 'true' if the given trip stops at the origin THEN the destination." | |
[origin destination trip] | |
(let [ts (filter #(or (= origin %) | |
(= destination %)) | |
(map :stop (:stops trip)))] | |
(if (seq ts) | |
(and (= origin (first ts)) | |
(= destination (first (rest ts))))))) | |
(defn- get-stop-info | |
"Gets the stop info for a stop in the context of a given trip" | |
[trip stop] | |
(if-let [ts (seq (filter #(= stop (:stop %)) (:stops trip)))] | |
(first ts))) | |
(defn is-after? | |
"Returns 'true' if the given trip gets to the origin after the given time." | |
[origin time trip] | |
(if-let [stop-info (get-stop-info trip origin)] | |
(is-date-after? (:time stop-info) | |
time))) | |
(defn get-all-trips | |
"Returns all trips after 'time-now' that can take someone from 'origin' to 'destination'" | |
[trips time-now origin destination] | |
(->> trips | |
(filter (partial goes-to? origin destination)) | |
(filter (partial is-after? origin time-now)))) | |
(defn- get-time-at | |
"Given a stop and a trip, gets the time of the trip at that stop" | |
[stop trip] | |
(if-let [stop-info (get-stop-info trip stop)] | |
(:time stop-info))) | |
(defn earliest | |
"Given a stop and 2 trips, returns the trip which arrives | |
at that stop earlier" | |
[stop trip1 & [trip2 _]] | |
(if (and trip2 | |
(is-date-after? (get-time-at stop trip1) | |
(get-time-at stop trip2))) | |
trip2 | |
trip1)) | |
(defn get-earliest | |
[trips time-now origin destination] | |
(let [reduce-fn (partial earliest origin) | |
candidates (get-all-trips trips time-now origin destination)] | |
(if (seq candidates) | |
(reduce reduce-fn | |
candidates)))) | |
(defn run-tests | |
"Some really basic tests (obviously we'd use clojure.test for this in a real app)" | |
[] | |
(assert (= 0 (:id (get-earliest trips "2015-07-15T18:46" "Wynyard" "Town Hall")))) | |
(assert (= 1 (:id (get-earliest trips "2015-07-15T18:47" "Wynyard" "Town Hall")))) | |
(assert (nil? (get-earliest trips "2015-07-15T18:48" "Wynyard" "Town Hall"))) | |
(assert (nil? (get-earliest trips "2015-07-15T18:46" "Town Hall" "Wynyard")))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment