Re: Help with my vec matching function
I would write this like that: (def v #{[1 2 3] [9 8 3] [1 2] [1] [1 0 3 4] [1 2 3 4 5]} ) (defn better-match [pattern match1 match2] ;;here choosing better matching vec from these 2 - sorry, I'm too lazy :) ) (reduce #(better-match [1 2 3] %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
Re: Help with my vec matching function
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
Re: Help with my vec matching function
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
Re: Help with my vec matching function
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
Re: Help with my vec matching function
On 28 Gru, 20:57, Robert Campbell rrc...@gmail.com wrote: How might I add a third and final condition, where those candidates with equal scores AND equal counts are all returned together? Reduce can work with functions like f : x * y - x So we can modify function closest to be like that (untested): (closest [ v1s v2] (if (empty v1s) v2 (cond (and (= (matching (first v1s)) (matching v2)) (= (count (first v1s)) (count v2))) (into v1s v2)) (or ( (matching (first v1s)) (matching v2)) (and (= (matching (first v1s)) (matching v2)) ( (count (first v1s)) (count v2 [v1] :else [v2]))) Also, we use matching on the same arguments a lot, so it would be good to memoize that function. -- 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
Re: Help with my vec matching function
That makes sense. I updated the function to: (defn closest-match Returns the closest matches of needle in the haystack [#^IPersistentVector needle #^IPersistentVector haystack] (letfn [(matching [candidate] (println checking candidate) (reduce + (map #(if (= %1 %2) 1 0) needle candidate))) (closest [v1s v2] (cond (empty? v1s) [v2] (and (= (matching (first v1s)) (matching v2)) (= (count (first v1s)) (count v2))) (conj v1s v2) (or ( (matching (first v1s)) (matching v2)) (and (= (matching (first v1s)) (matching v2)) ( (count (first v1s)) (count v2 v1s :else [v2]))] (reduce #(closest %1 %2) [] haystack))) This does work now: (closest-match [1 2 3] #{[1 2 \a] [1 2 \b] [2 1] [1] [1 2 \c] [1 2 3 4 5]}) [[1 2 3 4 5]] (closest-match [1 2] #{[1 2 \a] [1 2 \b] [2 1] [1] [1 2 \c] [1 2 3 4 5]}) [[1 2 \b] [1 2 \c] [1 2 \a]] (closest-match [2 1 3] #{[1 2 \a] [1 2 \b] [2 1] [1] [1 2 \c] [1 2 3 4 5]}) [[2 1]] One place I'm going to try to improve upon is how it reacts when there are no matches. Right now, it will return the smallest candidate because the third cond predicate will be true: (and (= (matching (first v1s)) (matching v2)) ; (= 0 0) ( (count (first v1s)) (count v2 v1s ; basically finds the smallest candidate (closest-match [\a \b] #{[1 2 \a] [1 2 \b] [2 1] [1] [1 2 \c] [1 2 3 4 5]}) [[1]] (closest-match [\a \b] #{[1 2 \a] [1 2 \b] [2 1] [1] [1 2 \c] [1 2 3 4 5] []}) [[]] I think when matches = 0, or there is literally no intersection between the needle and the candidates, I will just return []. Rob On Mon, Dec 28, 2009 at 6:28 PM, ajuc aju...@gmail.com wrote: On 28 Gru, 20:57, Robert Campbell rrc...@gmail.com wrote: How might I add a third and final condition, where those candidates with equal scores AND equal counts are all returned together? Reduce can work with functions like f : x * y - x So we can modify function closest to be like that (untested): (closest [ v1s v2] (if (empty v1s) v2 (cond (and (= (matching (first v1s)) (matching v2)) (= (count (first v1s)) (count v2))) (into v1s v2)) (or ( (matching (first v1s)) (matching v2)) (and (= (matching (first v1s)) (matching v2)) ( (count (first v1s)) (count v2 [v1] :else [v2]))) Also, we use matching on the same arguments a lot, so it would be good to memoize that function. -- 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
Re: Help with my vec matching function
A technique that works for me is to create sequences which are augmented with properties and then filter and transform those sequences in a kind of pipeline. Using that approach I came up with the following: (defn eval-candidate [needle candidate] Returns a map representing derived information about the candidate vector and its fit with the search target (needle) vector {:score (reduce + (map #(if (= %1 %2) 1 0) needle candidate)) :len (count candidate) :vec candidate} ) (defn closest-match [needle haystack] Tries to find the best fit for the given needle vector in the haystack of candidate vectors (let [augmented (map (partial eval-candidate needle) haystack) max-score (apply max (map :score augmented))] (if (= max-score 0) ; no good matches at all [] (let [candidates (filter #(= max-score (:score %)) augmented)] (if ( (count candidates) 1) ; a single match wins (let [min-length (apply min (map :len candidates)) winners (filter #(= min-length (:len %)) candidates)] (map :vec winners) ) (map :vec candidates) ) ) ) ) ) cheers, -tom -- 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