Re: How to Sum a Sequence?
On Sun, 20 Mar 2011 08:47:30 -0700 (PDT) Christian soulbea...@gmail.com wrote: Hello Tassilo! I've tested your code and looked at the Clojure Documentation for 'for'. Given that, I have written (reduce +(filter even? (for [fib (fib-seq) :while ( fib 400)] fib))) This gives me the error 'clojure.lang.LazySeq cannot be cast to clojure.lang.IFn'. I think this is because fib-seq is a var, not a function (although I was hard-pressed finding out what IFn stood for.) When I omit the () with [fib (fib-seq)...], the program works just as expected. Since nobody answered the implied question: yes, you're right. The fix is to just remove the ()'s from fib-seq to reference it directly, like so: (reduce + (for [fib fib-seq :while ( fib 400) :when (even? fib)] fib)) Note that I replaced the filter with the for loops :when test. No real reason, it just feels more natural to use what for offers since you started with it. Personally, I'd probably use Daniel's filter/take-while solution. mike -- Mike Meyer m...@mired.org http://www.mired.org/consulting.html Independent Software developer/SCM consultant, email for more information. O ascii ribbon campaign - stop html mail - www.asciiribbon.org -- 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
How to Sum a Sequence?
I've tried Project Euler 2 now. For those unfamiliar, Project Euler Problem 2 states: find the sum of all even-valued fibonacci terms that are less than four million. Let's assume that I have the code to fill the vector: (def fib-seq ((fn rfib [a b] (lazy-seq (cons a (rfib b (+ a b) 0 1)) (def fib-vec (into [] (filter even? (take 35 fib-seq Many people reading the Clojure Samples will be familiar with the first sample. My own implementation did not want the 'take' function to work. However, that is a question for another day. Assume that the magic number 35 in the second function does indeed give me all even- valued fibonacci terms under four million. (I did not know how to specify a predicate depending on the value of (fib-seq) to check if the value is under 4 million.) With the function '(reduce + (fib-vec))' I effortlessly summed up all values in the vector. This is peculiar, because I first wanted to write a function that does this for me, but to no avail. (defn answer [] (let [ansVec [0]] (while (not-empty fib-vec) (conj ansVec (+ (last ansVec) (last fib-vec))) (into fib-vec (pop fib-vec) This function never terminates. Why not? Where am I thinking wrong? -- 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: How to Sum a Sequence?
Hi Christian, What you're trying to do is to build up a vector with the last element of the vector being the answer to your problem: (last answer) = 4613732 You're trying to use cons (conj) to build up that list. Now, your function below never terminates because you're: a) Not actually building up the ans-vec b) Not actually changing fib-vec to be closer to termination Clojure datastructures are immutable. conj returns a new seq with the second argument conj(s)ed onto the old sequence without changing the old seq e.g.: (def v [1 2 3]) (conj v 4) = [1 2 3 4] but: v = [1 2 3] The same applies to into. The closest I can think of you're trying to achieve is: (defn answer [] (loop [ans-vec [0] fib-v fib-vec] (if (empty? fib-v) ans-vec (recur (conj ans-vec (+ (last ans-vec) (last fib-v))) (pop fib-v) Now you're actually building up ans-vec in a tail-recursive fashion while changing fib-v to be closer to termination. Having said that, what you really want is (reduce + fib-vec) ;) Andreas P.S. To get your head around basic recursion dig into The little Schemer by Friedman and Felleisen On 20/03/2011, at 7:22 PM, Christian wrote: I've tried Project Euler 2 now. For those unfamiliar, Project Euler Problem 2 states: find the sum of all even-valued fibonacci terms that are less than four million. Let's assume that I have the code to fill the vector: (def fib-seq ((fn rfib [a b] (lazy-seq (cons a (rfib b (+ a b) 0 1)) (def fib-vec (into [] (filter even? (take 35 fib-seq Many people reading the Clojure Samples will be familiar with the first sample. My own implementation did not want the 'take' function to work. However, that is a question for another day. Assume that the magic number 35 in the second function does indeed give me all even- valued fibonacci terms under four million. (I did not know how to specify a predicate depending on the value of (fib-seq) to check if the value is under 4 million.) With the function '(reduce + (fib-vec))' I effortlessly summed up all values in the vector. This is peculiar, because I first wanted to write a function that does this for me, but to no avail. (defn answer [] (let [ansVec [0]] (while (not-empty fib-vec) (conj ansVec (+ (last ansVec) (last fib-vec))) (into fib-vec (pop fib-vec) This function never terminates. Why not? Where am I thinking wrong? -- 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 www.leica-geosystems.com* when it has to be right, Leica Geosystems Please consider the environment before printing this email. -- 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: How to Sum a Sequence?
Christian soulbea...@gmail.com writes: Hi Christian, For those unfamiliar, Project Euler Problem 2 states: find the sum of all Sounds like (reduce + ...). even-valued fibonacci terms Sounds like (filter even? ...) that are less than four million. Hm, that's a bit more challenging. I think, you could go with (for [fib (fib-seq) :while ( fib 400)] fib) Of course, this is all completely untested. :-) Bye, Tassilo -- 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: How to Sum a Sequence?
Hello Tassilo! I've tested your code and looked at the Clojure Documentation for 'for'. Given that, I have written (reduce +(filter even? (for [fib (fib-seq) :while ( fib 400)] fib))) This gives me the error 'clojure.lang.LazySeq cannot be cast to clojure.lang.IFn'. I think this is because fib-seq is a var, not a function (although I was hard-pressed finding out what IFn stood for.) When I omit the () with [fib (fib-seq)...], the program works just as expected. I would like to thank you for this suggestion and the way you translated the problem statement into code! Do you have any resources or books that help with such things? (Taking a problem and solving it the way you did) On Mar 20, 11:18 am, Tassilo Horn tass...@member.fsf.org wrote: Christian soulbea...@gmail.com writes: Hi Christian, For those unfamiliar, Project Euler Problem 2 states: find the sum of all Sounds like (reduce + ...). even-valued fibonacci terms Sounds like (filter even? ...) that are less than four million. Hm, that's a bit more challenging. I think, you could go with (for [fib (fib-seq) :while ( fib 400)] fib) Of course, this is all completely untested. :-) Bye, Tassilo -- 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: How to Sum a Sequence?
Hi On 20 March 2011 17:47, Christian soulbea...@gmail.com wrote: Hello Tassilo! I've tested your code and looked at the Clojure Documentation for 'for'. Given that, I have written (reduce +(filter even? (for [fib (fib-seq) :while ( fib 400)] fib))) Or using Daniel's suggestion: (reduce + (filter even? (take-while #( % 400) fib-seq))) This gives me the error 'clojure.lang.LazySeq cannot be cast to clojure.lang.IFn'. I think this is because fib-seq is a var, not a function (although I was hard-pressed finding out what IFn stood for.) When I omit the () with [fib (fib-seq)...], the program works just as expected. Yes, that's correct. IFn means something that implements the Fn interface, i.e. it acts like a function. There are things in Clojure which are not really functions, but can be used like functions. e.g.: ({:foo bar} :foo) or: (:foo {:foo bar}) -- Michael Wood esiot...@gmail.com -- 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: How to Sum a Sequence?
Christian soulbea...@gmail.com writes: Hi Christian, I would like to thank you for this suggestion and the way you translated the problem statement into code! Thanks for the compliment. :-) Do you have any resources or books that help with such things? (Taking a problem and solving it the way you did) I think, my suggestions are not specific to clojure, but they apply to any functional language. All of them have functions for filtering sequences, applying a function to each item, reducing, and so on. Once you know these basic functions, most computation can be expressed by composing these in some way. Bye, Tassilo -- 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: How to Sum a Sequence?
Do you have any resources or books that help with such things? (Taking a problem and solving it the way you did) I think, my suggestions are not specific to clojure, but they apply to any functional language. All of them have functions for filtering sequences, applying a function to each item, reducing, and so on. Once you know these basic functions, most computation can be expressed by composing these in some way. I can only speak for me personally, but I found it useful going through the excellent books the CLisp and Scheme community provide. Peter Seibels Practical Common Lisp and The Little Schemer, The Seasoned Schemer, and of course SICP not only teach you how to use a Lisp which is 'simpler' than Clojure (not in terms of syntax) - this is especially true for Scheme (not so much CLisp) but they also teach you how to recognise certain patterns that occur in functional programs. Once you know how those patterns match to the sequence functions you can start replacing them and writing more concise code. That was my path anyway and I'm still learning :) It's fun though, don't get frustrated :) This community is very helpful so don't hesitate and ask. There's no dumb questions, you know the saying. Andreas -- 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