Commits

Robert Smith committed 7443dee

PARTITION-IF and EQUIVALENCE-CLASSES

Comments (0)

Files changed (1)

partition-if.lisp

+;;;; partition-if.lisp
+;;;; Copyright (c) 2013 Robert Smith
+
+;;;; Implementations of PARTITION-IF and EQUIVALENCE-CLASSES.
+
+#+(or)
+(defun partition-if (f list)
+  (loop :for x :in list
+        :if (funcall f x)
+          :collect x :into yes
+        :else
+          :collect x :into no
+        :finally (return (list yes no))))
+
+(defun partition-if (f seq)
+  "Partition the sequence SEQ into a list of elements satisfying the
+predicate F and a list of elements who do not."
+  (let ((yes nil)
+        (no nil))
+    (map nil
+         (lambda (x)
+           (if (funcall f x)
+               (push x yes)
+               (push x no)))
+         seq)
+    (list (nreverse yes)
+          (nreverse no))))
+
+(defun equivalence-classes (equiv seq)
+  "Partition the sequence SEQ into a list of equivalence classes
+according to the equivalence relation EQUIV."
+  (let ((half-length (floor (length seq) 2))
+        (classes nil))
+    (labels ((find-equivalence-class (x)
+               (find-if (lambda (class)
+                          (funcall equiv (aref class 0) x))
+                        classes))
+             
+             (new-class (x)
+               (make-array half-length
+                           :initial-element x
+                           :adjustable t
+                           :fill-pointer 1))
+             
+             (add-to-class (x)
+               (let ((class (find-equivalence-class x)))
+                 (if class
+                     (vector-push-extend x class)
+                     (push (new-class x) classes)))))
+      
+      ;; Partition into equivalence classes.
+      (map nil #'add-to-class seq)
+      
+      ;; Return the classes.
+      classes)))
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.