On Mon, Nov 8, 2010 at 8:34 PM, Greg <[email protected]> wrote:
> On Nov 8, 2010, at 3:11 PM, Ken Wesson wrote:
>
>> (defn new-gen [a]
>> (distinct #(= (:val %1) (:val %2))
>> (for [f a
>> n [(transform-left f) (transform-right f)]
>> :when (not (contains? #(= (:val n) %) (map :val (parents n))))]
>> n)))
>>
>> is more functional but possibly slower.
>
> This is nice, and it's actually very similar to one of my first attempts, as
> I used 'for' too, but I couldn't figure out how to use just a single 'for'. I
> didn't know that you could do that secondary assignment for 'n' like that.
> This is one of my favorite solutions I think.
Thanks.
It can be done without the double-barreled "for", though, if you
really want it that way:
(defn new-gen [a]
(distinct #(= (:val %1) (:val %2))
(mapcat
(fn [f]
(for [n [(transform-left f) (transform-right f)]
:when (not (contains? #(= (:val n) %) (map :val (parents n))))]
n))
a))))
:-)
>
>> If you really just want the first one in traversal order with each
>> distinct value, though, you could just use
>>
>> (defn new-gen [a]
>> (distinct #(= (:val %1) (:val %2))
>> (apply concat
>> (for [f a]
>> [(transform-left f) (transform-right f)]))))
>>
>> which makes distinct do all the heavy lifting (the whole rest of it is
>> just the traversal).
>
> This seems to be missing the check for the rule #1 (making sure the parents
> don't have the same value) though...
True. That would only work if the parents were in the output somewhere.
As you formulated it, if a child of one node had value foo and a child
of a different node had value foo, one would be omitted; the way you
originally worded the problem it sounded like only when both children
of a single node had the same value should one be omitted. If you want
that behavior instead you need
(defn new-gen [a]
(mapcat
(fn [f]
(let [g (transform-left f)
h (transform-right f)]
(if (= (:val g) (:val f))
(if-not (= (:val h) (:val f)) [h])
(if (or (= (:val h) (:val f)) (= (:val h) (:val g)))
[g]
[g h]))))))
or maybe this version suits you better:
(defn new-gen [a]
(let [test #(= (:val %1) (:val %2))]
(mapcat
(fn [f]
(let [s (distinct test
[f (transform-left f) (transform-right f)])]
(remove #(test % f) s))))))
> Thanks for your solutions! It's very helpful for learning Clojure.
You're welcome.
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en