Created
December 23, 2011 23:02
-
-
Save noahlz/1515617 to your computer and use it in GitHub Desktop.
LabRepl looping exercises
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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
;; LabREPL min-3 exercise | |
;; "Implement min-3 which reduces over a function that returns | |
;; the min of two arguments" | |
;; My attempt | |
(defn min-3 [x & more] | |
(let [s (cons x (seq more))] | |
reduce (fn findmin [x y] (if (< x y) x y)) s))) | |
;; #'user/min-3 | |
(min-3 1 2 3 4) | |
;; 1 | |
(min-3 1 2 3 -4) | |
;; -4 | |
(min-3 1 2 3 -7 -8 32 -100 12 4 1000) | |
;;-100 | |
;; Solution | |
(defn min-3 [& coll] | |
(reduce (fn [x y] (if (< x y) x y)) coll)) | |
;; #'user/min-3 | |
(min-3 1 2 3 -7 -8 32 -100 12 4 1000) | |
;; -100 | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
;; LabREPL zipm exercises | |
;; "One option is to loop over three variables: the result map m (which gets | |
;; bigger), and the input sequences ks and vs (which get smaller). Create a | |
;; zipm-1 that uses a loop and assoc to build the result map." | |
;; My implementation - forgot that keys and values might not be sequences. | |
(defn zipm-1 [keys values] | |
(loop [[k & ks] keys | |
[v & vs] values | |
m {}] | |
(if (and k v) | |
(recur ks vs (assoc m k v)) | |
m))) | |
;; #'user/zipm-1 | |
(zipm-1 [:a :b :c] [1 2 3]) | |
;; {:c 3, :b 2, :a 1} | |
(zipm-1 [:d :a :b :c] [1 2 3 4]) | |
;; {:c 4, :b 3, :a 2, :d 1} | |
;; The solution... | |
(defn zipm-2 | |
[keys vals] | |
(loop [m {} | |
[k & ks :as keys] (seq keys) | |
[v & vs :as vals] (seq vals)] | |
(if (and keys vals) | |
(recur (assoc m k v) ks vs) | |
m))) | |
;; I actually implemented the solution for zipm-2... | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
;; LabREPL minmax exercise | |
;; Implement minmax-2 using reduce. Think carefully about the reduction | |
function. It needs to hold two values at each iteration: one each for min and max. | |
(defn minmax-2 | |
[& coll] | |
(reduce (fn [m val] | |
(let [oldmin (if m (:min m) nil) | |
oldmax (if m (:max m) nil) | |
newmin (if oldmin (if (< val oldmin) val oldmin) val) | |
newmax (if oldmax (if (> val oldmax) val oldmax) val)] | |
(assoc {} :min newmin :max newmax))) {} coll)) | |
(minmax-2 1 2 3 4 5) | |
;; {:max 5, :min 1} | |
(minmax-2 -100 2 87 29 1000 284 29) | |
;; {:max 1000, :min -100} | |
(minmax-2 -100 2 87 29 1000 284 29 -10000000 1/2) | |
;; {:max 1000, :min -10000000} | |
;; The solution - merge-with FTW | |
(defn minmax-2 | |
[x & more] | |
(reduce | |
(fn [result x] | |
(->> result | |
(merge-with min {:min x}) | |
(merge-with max {:max x}))) | |
{:min x :max x} | |
more)) | |
;; NOTE - the ->> makes the above roughly equivalent to the following: | |
(defn minmax-2 | |
[x & more] | |
(reduce (fn [result x] | |
(merge-with min {:min x} (merge-with max result {:max x}))) | |
{:min x :max x} | |
more)) | |
(minmax-2 -100 2 87 29 1000 284 29 -10000000 Integer/MAX_VALUE) | |
;; (:min -10000000, :max 2147483647} | |
(minmax-2 -100 2 87 29 1000 284 29) | |
;; {:min -100, :max 1000} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment