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 <[email protected]> wrote:
> On Feb 14, 5:49 pm, Glen Rubin <[email protected]> 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" <[email protected]> wrote:
>
> > > Glen Rubin <[email protected]> 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 [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