Hi,

>From a cursory glance, I didn't really understand the domain, so the 
function names I used in my rewrite might seem silly. But I wanted to 
illustrate that there is a lot of repetition in your code. Also discrete 
functions (with proper names) can make the code easier to grok. 

https://gist.github.com/amithgeorge/15b1cb607c32d39b70c7

;; instead of relying on the caller to pass the edges in the right order,
;; we accept a map and process the keys in the correct order

(defn- squared-edge-values
  [edges]
  (->> [:oc :oa :ob :ca :ab :bc]
       (map #(edges %1))
       (map #(* %1 %1))))

;; all operations on the edges are performed on the squared values.
;; the squared values are guaranteed to be in the correct order.

;; this separates out the logic specific to opposite edges and can be tested 
separately
(defn- opposite-edge-values
  [edges]
  (let [[a2 b2 c2 d2 e2 f2] (squared-edge-values edges)]
    [[a2 e2 (+ a2 e2)]
     [b2 f2 (+ b2 f2)]
     [c2 d2 (+ c2 d2)]]))

(defn- closed-edge-values
  [edges]
  (let [[a2 b2 c2 d2 e2 f2] (squared-edge-values edges)]
    [[a2 b2 d2]
     [d2 e2 f2]
     [b2 c2 e2]
     [a2 c2 f2]]))

(defn- open-edge-values
  [edges]
  ;; implement later
  [[0 0 0]])

(defn- compute-edge-values
  [edge-fn edges]
  (->> edges
       (edge-fn)
       (map (fn [[x y z]] (* x y z)))
       (reduce +)))

(def ^:private add-opposite (partial compute-edge-values opposite-edge-values))
(def ^:private add-closed (partial compute-edge-values closed-edge-values))
(def ^:private add-open (partial compute-edge-values open-edge-values))

;; this is the public entry point.
;; the precondition ensures all the edges are present in the input

(defn volume 
  [{:keys [oa ob oc ab bc ca] :as edges}]
  {:pre [(every? #(number? %1) [oa ob oc ab bc ca])]}
  (let [opposite (add-opposite edges)
        closed (add-closed edges)
        open (add-open edges)]
    (Math/sqrt (* (- (- open closed) opposite) 0.5))))


;; sample input
(defn a-mod-input
  []
  (let [a 1.0]
    {:oc (* a (/ (Math/sqrt 6.0) 12.0))
     :oa (* a (/ (Math/sqrt 6.0) 4.0))
     :ob (* a (/ (Math/sqrt 2.0) 4.0))
     :ca (* a (/ (Math/sqrt 3.0) 3.0))
     :ab (/ a 2.0)
     :bc (* a (/ (Math/sqrt 3.0) 6.0))}))

(defn e-mod-input
  []
  (let [d 1.0
        r (/ d 2.0)
        h r]
    {:oc h
     :oa 1
     :ob 1
     :ca 1
     :ab 1
     :bc 1}))

(def a-mod-volume (volume (a-mod-input)))
(def e-mod-volume (volume (e-mod-input)))


Again, the idea is to have small functions that reflect the steps you would 
normally do, as required by the domain or algo you are implementing. 

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to