/merge-date-style2.clj Secret
Last active
October 14, 2016 13:22
merge-date
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 merge-date.core) | |
(def sorted-time-range (sort-by first '([1 3] [3 4] [47 52] [12 44]))) | |
(defn merge-date-tuple [[b0 e0] [b1 e1]] | |
(if (>= e0 b1) | |
[[b0 (max e0 e1)]] | |
[[b0 e0] [b1 e1]])) | |
(defn merge-date | |
([coll] (merge-date (rest coll) | |
[(first coll)])) | |
([coll res] (if (empty? coll) | |
res | |
(recur (rest coll) | |
(concat (drop-last res) | |
(merge-date-tuple (last res) | |
(first coll))))))) | |
(println "===> result " (merge-date sorted-time-range)) |
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
;; heavy use of destructuring | |
(defn merge-date [coll] | |
(let [s (sort-by first coll) | |
{a :a p :p} (reduce (fn [{[p1 p2 :as p] :p a :a} [x1 x2 :as el]] | |
(if (>= p2 x1) | |
{:a a :p [p1 x2]} | |
{:a (conj a p) :p el})) | |
{:a [] :p (first s)} (rest s))] | |
(concat a p))) | |
(merge-date '([1 3] [3 4] [47 52] [12 44])) |
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
;; small gist to compare a merge date algorithm in Clojure with another language (code not here) | |
(ns merge-date.core) | |
;; fake step 1 | |
;; define a variable for the unsorted array | |
(def unsorted-time-range '([1 3] [3 4] [47 52] [12 44])) | |
;; step 2 : sort the array and store it in sorted-time-range | |
(def sorted-time-range (sort-by first unsorted-time-range)) | |
(println "sorted " sorted-time-range) | |
;; step 3 | |
; helper function to merge two time slots | |
(defn merge-date-tuple | |
[[b0 e0] [b1 e1]] ; function arguments (destructured) | |
{:pre [(<= b0 e0) ; (optionnal) preconditions | |
(<= b1 e1) | |
(<= b0 b1)]} | |
(if (>= e0 b1) ; if(end-date-current >= begin-date-next | |
[[b0 (max e0 e1)]] ; true => merge | |
[[b0 e0] [b1 e1]])) ; false => return arguments | |
; merge an array of time slots | |
(defn merge-date | |
;; called with only one argument : the collection (array of time slots) | |
;; initialise the res variable with the first element from the sorted collection | |
([coll] (merge-date (rest coll) [(first coll)])) | |
;; two arguments : the collection to be merged, the result already merged | |
([coll res] (if (empty? coll) | |
res ; done, return result | |
; define variables | |
(let [current (last res) ; current : first element of res | |
next (first coll) ; next : first element of coll | |
merged (merge-date-tuple current next)] ; merge current and next using helper function | |
;; call the function again (recursive) with two arguments : | |
;; - the rest of the collection to be merged | |
;; - the partial result constructed so far (by concatenating the previous result with the merged tuple) | |
(println "\n") | |
(println "to be merged", (rest coll)) | |
(println "already merged", (concat (drop-last res) merged)) | |
(recur (rest coll) (concat (drop-last res) merged)))))) | |
(println "===> result " (merge-date sorted-time-range)) | |
;; prints the following : | |
; sorted ([1 3] [3 4] [12 44] [47 52]) | |
; to be merged ([12 44] [47 52]) | |
; already merged ([1 4]) | |
; to be merged ([47 52]) | |
; merged ([1 4] [12 44]) | |
; to be merged () | |
; already merged ([1 4] [12 44] [47 52]) | |
===> result ([1 4] [12 44] [47 52]) |
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
(defn md [coll] | |
(let [[f & r] (sort-by first coll)] | |
(if f | |
(reduce (fn [a e] | |
(let [[b1 e1] e | |
[b0 e0] (last a) | |
c (count a)] | |
(if (<= b1 e0) | |
(assoc a (dec c) [b0 e1]) | |
(assoc a c e)))) [f] r) | |
[]))) | |
;;commented | |
;; define a function "md" that takes a collection in parameter | |
(defn md [coll] | |
;; sort the collection by the first item (begin date) | |
;; and destructure it into the first element and the rest | |
(let [[f & r] (sort-by first coll)] | |
;; if there is a first element (ie. if the collection is not empty) | |
(if f | |
;; then loop over it, one element at a time | |
(reduce (fn [a e] | |
;; a contains the result that is being built every iteration (a=accumulator) | |
;; e contains the new element that we want to add | |
(let [;; destructure the last element from the result into a beginning date b0 and an end date e0 | |
[b0 e0] (last a) | |
;; destructure the new element into the beginning b1 and the end e1 | |
[b1 e1] e | |
;; get the number of elements that we have already in the result vector. Accessing a at the index c - 1 will point to the last element of the vector | |
c (count a)] | |
(if (<= b1 e0) ;; if we want to merge the dates | |
;; then replace the last element of a (at index c - 1) with a couple [b0 e1] | |
(assoc a (dec c) [b0 e1]) | |
;; if don't want to merge the date, then add the new element at the end of the vector (index c) | |
(assoc a c e)))) [f] r) | |
;; if it was empty then return an empty array | |
[]))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment