diff --git a/numbers.lisp b/numbers.lisp
index bf6ef0bf2ee46e6276b8777fc64805fbbbf73afb..0fa29a43b06d63868eb630fb0c460e73e4586c7c 100644
--- a/numbers.lisp
+++ b/numbers.lisp
@@ -210,6 +210,10 @@ greater then K."
   (if (or (zerop k) (= n k))
       1
       (let ((n-k (- n k)))
+        ;; Swaps K and N-K if K < N-K because the algorithm
+        ;; below is faster for bigger K and smaller N-K
+        (when (< k n-k)
+          (rotatef k n-k))
         (if (= 1 n-k)
             n
             ;; General case, avoid computing the 1x...xK twice:
@@ -231,8 +235,8 @@ greater then K."
 
 (defun count-permutations (n &optional (k n))
   "Number of K element permutations for a sequence of N objects.
-R defaults to N"
-  ;; FIXME: Use %multiply-range and take care of 1 and 2, plus
-  ;; check types.
-  (/ (factorial n)
-     (factorial (- n k))))
+K defaults to N"
+  (check-type n (integer 0))
+  (check-type k (integer 0))
+  (assert (>= n k))
+  (%multiply-range (1+ (- n k)) n))
diff --git a/tests.lisp b/tests.lisp
index c13956850ba38b0543c793423c9f42bcc510af16..b9e2277bc2d0b9a6b2bd8575c3ca61c506c90226 100644
--- a/tests.lisp
+++ b/tests.lisp
@@ -1712,3 +1712,21 @@
   (1 2 3)
   nil
   nil)
+
+(deftest count-permutations.1
+    (values (count-permutations 31 7)
+            (count-permutations 1 1)
+            (count-permutations 2 1)
+            (count-permutations 2 2)
+            (count-permutations 3 2)
+            (count-permutations 3 1))
+  13253058000
+  1
+  2
+  2
+  6
+  3)
+
+(deftest binomial-coefficient.1
+    (alexandria:binomial-coefficient 1239 139)
+  28794902202288970200771694600561826718847179309929858835480006683522184441358211423695124921058123706380656375919763349913245306834194782172712255592710204598527867804110129489943080460154)