Thank you so much!!!! This is really wonderful advice...saved me months of learning. I have rewritten my code as follows:
;definition of a palindrome (defn palindrome? [s] (= s (apply str (reverse s)))) ;list of palindromes for range of numbers (defn palindromes [start end] (def startmod (- start 1)) (filter #(palindrome? (str %)) (range (* end end) (* startmod startmod) -1))) ;yields a lazy sequence of all that are divisible by a 3 digit number and yield a 3 digit quotient (defn divis-by-3dig [pal] (filter #(if (zero? (mod pal %)) (< 99 (unchecked-divide pal %) 1000)) (range 999 99 -1))) (defn p1 [] (def palindromic-number (first (filter #(seq (divis-by-3dig %)) (palindromes 100 999)))) (def root1 (first (divis-by-3dig palindromic-number))) (def root2 (unchecked-divide palindromic-number root1)) (def message (str "the palindromic number is " palindromic-number " its roots are " root1" " root2)) message) On Feb 14, 11:17 pm, ataggart <alex.tagg...@gmail.com> wrote: > On Feb 14, 5:49 pm, Glen Rubin <rubing...@gmail.com> wrote: > > > > > Thank you for the advice! Just for reference I am working on project > > euler question #4 (Find the largest palindrome made from the product > > of two 3-digit numbers.) > > > I have a solution, but am hoping somebody can clarify some things for > > me: > > > First, I define a panlindrome tester: > > > (defn palindrome? [s] > > (= s (apply str (reverse s)))) > > > Next, I define a list of palindromes for the two 3-digit number range: > > > (def palindromes (filter #(palindrome? (str %)) (reverse (range (* 100 > > 100) (+ 1 (* 999 999)))))) > > > My next function takes a palindromic number as an argument and returns > > a sequence of all 3 digit divisors with a 3 digit quotient > > > (defn divis-by-3dig [pal] (filter #(if (zero? (mod pal %)) (= 3 (len > > (str (/ pal %))))) (reverse (range 100 1000)))) > > > This function works, but only with an integer, which means I have to > > use it with another filter function in order to test a collection. > > And then it will return the palindromic number in my collection which > > has two 3 digit divisors instead of the factors, which is what I am > > looking for. > > > I solve this as follows in my main function: > > > (defn e1 [] > > (def palindromic-number (take 1 (filter #(not (empty? (divis-by-3dig > > %))) palindromes))) > > (def root (take 1 (map divis-by-3dig palindromic-number))) > > root) > > > unfortunately there is still a problem with this, in that i cannot get > > access to a single root, instead am returned all of the roots from > > applying my divis-by-3dig function to the single element in my > > collection palindromic-number > > (e1) > > > On Feb 14, 8:52 am, "Steven E. Harris" <s...@panix.com> wrote: > > > > Glen Rubin <rubing...@gmail.com> writes: > > > > How do I take an element from one collection and test for no remainder > > > > (e.g. (zero? (mod x y)), when dividing by every element of the second > > > > collection, before processing the next item in the first collection? > > > > This form checks if every element of the second range is a factor of > > > every element in the first range: > > > > ,---- > > > | (let [r2 (range 100 150)] > > > | (every? > > > | #(every? (partial (comp zero? mod) %) r2) > > > | (range 1000 2000))) > > > `---- > > > > Note that the walk over (range 1000 2000) is the outer one, and the walk > > > over (range 100 150) ("r2") is the inner one. > > > > -- > > > Steven E. Harris > > So you're scanning all possible products, then back-tracking to figure > out which 3-digit factors can result in that value? Interesting, > though outside the scope of the actual PE question. > > A few comments: > > - There is no len function. Use count or .length for strings. > > - Don't def really long sequences; instead defn a function that > returns the sequence (which can then be garbage collected). Plus it > sucks when pasting into the repl and it tries to realize and print the > entire sequence. > > - Don't reverse ranges since doing so requires first generating the > entire (otherwise lazy) sequence; instead make the step negative, > e.g., (range 999 99 -1) > > - Clojure's numeric inequality functions can take more than 2 args, > thus you can call (< 99 % 1000) rather than testing the length of the > stringified number. > > - If you want integer dividing, cast to int or use unchecked-divide (I > prefer the latter which avoids the intermediate Ratio): > user=> (/ 3 4) > 3/4 > user=> (int (/ 3 4)) > 0 > user=> (unchecked-divide 3 4) > 0 > > - Per the documentation of empty?, use the idiom (seq x) rather than > (not (empty? x)) > > - See if you can avoid banging everything to/from strings. Maybe turn > an int to/from some collection of digits. > > - (take 1 foo) returns you a one-element (or empty) sequence. (first > foo) returns the first value (or nil). Use the latter when you really > just want the value. This, by the way, is why your answer to (e1) is > ((913 993)). -- 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