How might I add a third and final condition, where those candidates with equal scores AND equal counts are all returned together?
A first try was this: (defn closest-match "Searches the haystack vecs for the closest match to the needle vec" [#^IPersistentVector needle #^IPersistentVector haystack] (letfn [(matching [candidate] (reduce + (map #(if (= %1 %2) 1 0) needle candidate))) (closest [v1 v2] (cond (and (= (matching v1) (matching v2)) (= (count v1) (count v2))) [v1 v2] (or (> (matching v1) (matching v2)) (and (= (matching v1) (matching v2)) (< (count v1) (count v2)))) v1 :else v2))] (reduce #(closest %1 %2) [] haystack))) (closest-match [1 2] #{[1 2 \a] [1 2 \b] [2 1]}) [[1 2 \b] [1 2 \a]] (closest-match [1 2] #{[1 2] [1 2 \a] [1 2 \b] [2 1]}) [1 2] It looks good at first, but I quickly noticed that I broke the whole reduction by introducing a pair where we expend only a vec: (closest-match [1 2] #{[1 2 \a] [1 2 \b] [2 1] [1 2 \c]}) [1 2 \a] What we should be getting [[1 2 \a] [1 2 \b] [1 2 \c]] since each of them is equally close to [1 2 3] On Mon, Dec 28, 2009 at 5:20 PM, Robert Campbell <rrc...@gmail.com> wrote: > Thanks ajuc. > > I updated the implementation to match your algorithm: > > (defn closest-match > "Searches the haystack vecs for the closest match to the needle vec" > [#^IPersistentVector needle #^IPersistentVector haystack] > (letfn [(matching [candidate] > (reduce + (map #(if (= %1 %2) 1 0) needle candidate))) > (closest [v1 v2] > (if (or (> (matching v1) (matching v2)) > (and (= (matching v1) (matching v2)) > (< (count v1) (count v2)))) v1 v2))] > (reduce #(closest %1 %2) [] haystack))) > > It now factors in the second step, taking the shortest candidate. > > (closest-match [1 2 3] #{[1 2 3] [9 8 3] [1 2] [1] [1 0 3 4] [1 2 3 4 5]}) > > now correctly returns [1 2 3] instead of [1 2 3 4 5] > > > > > On Mon, Dec 28, 2009 at 4:23 PM, ajuc <aju...@gmail.com> wrote: >> I don't know if I understan correctly the requirements, but this is my >> try. >> >> >> (def v #{[1 2 3] [9 8 3] [1 2] [1] [1 0 3 4] [1 2 3 4 5]} ) >> >> (defn matching [p v] >> (reduce + (map #(if (= %1 %2) 1 0) p v))) >> >> (defn better-match [p v1 v2] >> (if >> (or >> (> (matching p v1) (matching p v2)) >> (and >> (= (matching p v1) (matching p v2)) (< (count v1) (count >> v2)))) >> v1 >> v2)) >> >> (reduce #(better-match [1 2 4 4 5] %1 %2) [] v) >> >> -- >> 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 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