aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorscgilardi <scgilardi@gmail.com>2009-03-01 15:26:15 +0000
committerscgilardi <scgilardi@gmail.com>2009-03-01 15:26:15 +0000
commit8ce94fbc65dd838d3fdf12046b7db29c4ab5ccb7 (patch)
treee308100745c2f49f9ed6539af149d54b47b96bea
parentd404530419fdb1f5b86cf7587305533d50bf8b5a (diff)
fix issue 30: add lcm function to clojure.contrib.math (with tests) from gnuvince
-rw-r--r--src/clojure/contrib/math.clj10
-rw-r--r--src/clojure/contrib/math/tests.clj23
2 files changed, 32 insertions, 1 deletions
diff --git a/src/clojure/contrib/math.clj b/src/clojure/contrib/math.clj
index 0f4ff622..f7176a59 100644
--- a/src/clojure/contrib/math.clj
+++ b/src/clojure/contrib/math.clj
@@ -10,6 +10,7 @@
;; otherwise returns a double.
;; abs - (abs n) is the absolute value of n
;; gcd - (gcd m n) returns the greatest common divisor of m and n
+;; lcm - (lcm m n) returns the least common multiple of m and n
;; The behavior of the next three functions on doubles is consistent
;; with the behavior of the corresponding functions
@@ -121,6 +122,15 @@ round always returns an integer. Rounds up for values exactly in between two in
(if (zero? b) a,
(recur b (mod a b))))))
+(defn lcm
+ "(lcm a b) returns the least common multiple of a and b"
+ [a b]
+ (when (or (not (integer? a)) (not (integer? b)))
+ (throw (IllegalArgumentException. "lcm requires two integers")))
+ (cond (zero? a) 0
+ (zero? b) 0
+ :else (abs (* b (quot a (gcd a b))))))
+
; Length of integer in binary, used as helper function for sqrt.
(defmulti #^{:private true} integer-length class)
(defmethod integer-length java.lang.Integer [n]
diff --git a/src/clojure/contrib/math/tests.clj b/src/clojure/contrib/math/tests.clj
index 19304924..64a77cfb 100644
--- a/src/clojure/contrib/math/tests.clj
+++ b/src/clojure/contrib/math/tests.clj
@@ -30,7 +30,28 @@
(are (= _1 _2)
(gcd 4 3) 1
(gcd 24 12) 12
- (gcd 24 27) 3))
+ (gcd 24 27) 3
+ (gcd 1 0) 1
+ (gcd 0 1) 1
+ (gcd 0 0) 0)
+ (is (thrown? IllegalArgumentException (gcd nil 0)))
+ (is (thrown? IllegalArgumentException (gcd 0 nil)))
+ (is (thrown? IllegalArgumentException (gcd 7.0 0))))
+
+(deftest test-lcm
+ (are (= _1 _2)
+ (lcm 2 3) 6
+ (lcm 3 2) 6
+ (lcm -2 3) 6
+ (lcm 2 -3) 6
+ (lcm -2 -3) 6
+ (lcm 4 10) 20
+ (lcm 1 0) 0
+ (lcm 0 1) 0
+ (lcm 0 0))
+ (is (thrown? IllegalArgumentException (lcm nil 0)))
+ (is (thrown? IllegalArgumentException (lcm 0 nil)))
+ (is (thrown? IllegalArgumentException (lcm 7.0 0))))
(deftest test-floor
(are (= _1 _2)