Thanks Jens for explaining the filter-map idiom and for the fun code example, very enlightening!<div><br></div><div>-Joe<br><br><div class="gmail_quote">On Mon, May 28, 2012 at 1:34 AM, Jens Axel Søgaard <span dir="ltr">&lt;<a href="mailto:jensaxel@soegaard.net" target="_blank">jensaxel@soegaard.net</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">2012/5/28 Joe Gilray &lt;<a href="mailto:jgilray@gmail.com">jgilray@gmail.com</a>&gt;:<br>
<div class="im">&gt; I created some Racket solutions to ProjectEuler #71.  Below is one that uses<br>
&gt; filter and map:<br>
&gt;<br>
&gt; (define (euler71c)<br>
&gt;   (numerator (apply max (filter (λ (n) (&gt; (/ 3 7) n)) (map (λ (n) (/ (floor<br>
&gt; (/ (* n 3) 7)) n)) (stream-&gt;list (in-range 2 1000000)))))))<br>
&gt;<br>
&gt; 1) I thought I might speed it up by using filter-map, but I cannot<br>
&gt; understand how to do it.  I read the 1 line I could find in the reference<br>
&gt; and it just doesn&#39;t help me<br>
<br>
</div>The function filter-map keeps non-false elements.<br>
The idiom is therefore to use (and (&gt; /37 n) n).<br>
The for and returns the last element only if all the preceding tests were true.<br>
<div class="im"><br>
&gt; 2) The code above takes about 4x the time of a simple for loop<br>
&gt; implementation.  What can I do to speed it up?<br>
<br>
</div>Avoid allocation of unnecessary intermediate lists.<br>
Most often fold can be used for this purpose.<br>
<br>
Btw - when benchmarking in DrRacket - turn of debugging.<br>
<br>
I tried a few things. The results were:<br>
<br>
cpu time: 5174 real time: 5430 gc time: 3368<br>
cpu time: 4628 real time: 4859 gc time: 3311<br>
cpu time: 4122 real time: 4288 gc time: 2952<br>
cpu time: 3295 real time: 3401 gc time: 2318<br>
cpu time: 2674 real time: 2721 gc time: 1861<br>
cpu time: 2699 real time: 2746 gc time: 1843<br>
<br>
/Jens Axel<br>
<br>
<br>
#lang racket<br>
<br>
(define end 1000000)<br>
<div class="im"><br>
(define (euler71c)<br>
  (numerator<br>
   (apply max<br>
</div>          (filter (λ (n) (&gt; 3/7 n))<br>
<div class="im">                  (map (λ (n) (/ (floor (/ (* n 3) 7)) n))<br>
</div>                       (stream-&gt;list (in-range 2 end)))))))<br>
<br>
(define (euler71d)<br>
  (numerator<br>
   (apply max<br>
          (filter (λ (n) (&gt; 3/7 n))<br>
<div class="im">                  (map (λ (n) (/ (floor (/ (* n 3) 7)) n))<br>
</div>                       (range 2 end))))))<br>
<br>
(define (euler71e)<br>
  (numerator<br>
   (apply max<br>
          (filter-map<br>
           (λ (m)<br>
             (define n (/ (floor (/ (* m 3) 7)) m))<br>
             (and (&gt; 3/7 n) n))<br>
           (range 2 end)))))<br>
<br>
(define (euler71f)<br>
  (numerator<br>
   (foldl (λ (m max-so-far)<br>
            (define n (/ (floor (/ (* m 3) 7)) m))<br>
            (if (&gt; 3/7 n)<br>
                (max n max-so-far)<br>
                max-so-far))<br>
          0<br>
          (range 2 end))))<br>
<br>
(define (euler71g)<br>
  (numerator<br>
   (for/fold ([max-so-far 0]) ([m (in-range 2 end)])<br>
     (define n (/ (floor (/ (* m 3) 7)) m))<br>
     (if (&gt; 3/7 n) (max n max-so-far) max-so-far))))<br>
<br>
(define (euler71h)<br>
  (define max-so-far 0)<br>
  (for ([m (in-range 2 end)])<br>
    (define n (/ (floor (/ (* m 3) 7)) m))<br>
    (set! max-so-far<br>
          (if (&gt; 3/7 n) (max n max-so-far) max-so-far)))<br>
  (numerator max-so-far))<br>
<br>
(define (test)<br>
  (let ([old-end end])<br>
    (set! end 10)<br>
    (begin0<br>
      (list (equal? (euler71c) (euler71d))<br>
            (equal? (euler71d) (euler71e))<br>
            (equal? (euler71e) (euler71f))<br>
            (equal? (euler71f) (euler71g))<br>
            (equal? (euler71g) (euler71h)))<br>
      (set! end old-end))))<br>
<br>
(define (benchmark-one f)<br>
  (collect-garbage)<br>
  (time (begin (f) (void))))<br>
<br>
(define (benchmark)<br>
  (benchmark-one euler71c)<br>
  (benchmark-one euler71d)<br>
  (benchmark-one euler71e)<br>
  (benchmark-one euler71f)<br>
  (benchmark-one euler71g)<br>
  (benchmark-one euler71h))<br>
</blockquote></div><br></div>