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

Reply via email to