Hi,<div><br></div><div>To continue our conversation about creating idiomatic Racket code, here is some code I wrote last night to solve <a href="http://projecteuler.net">projecteuler.net</a> problem #29:</div><div><br></div>
<div><div>(define (euler29a)</div><div>  ; calculate 99^2 - duplicates</div><div>  (- (sqr 99) </div><div>     (for/sum ([d &#39;(2 3 5 6 7 10)])</div><div>              (let ([lst &#39;()])</div><div>                (let loop ([exp 1])</div>
<div>                  (if (&gt; (expt d exp) 100) (- (length lst) (length (remove-duplicates lst)))</div><div>                      (begin</div><div>                        (for ([i (in-range 2 101)]) (set! lst (cons (* i exp) lst)))</div>
<div>                        (loop (add1 exp)))))))))</div></div><div><br></div><div>It&#39;s fast (it avoids calculating a bunch of huge numbers), it gives the correct answer, so what&#39;s not to love?!</div><div><br></div>
<div>Well, it starts off OK, but my eye stumbles over the following:</div><div><br></div><div>1) predeclaring lst and accessing it twice, related to each other</div><div>2) ugly single parameter named-let loop</div><div>3) ugly &quot;begin&quot; - not a big deal, but I just dislike when having to use begin</div>
<div>4) use of set!</div><div><br></div><div>Here is a quick rewrite:</div><div><br></div><div><div>(define (euler29b)</div><div>  ; calculate 99^2 - duplicates</div><div>  (- (sqr 99) </div><div>     (for/sum ([d &#39;(2 3 5 6 7 10)])</div>
<div>              (let ([lst &#39;()])</div><div>                (do ([exp 1 (add1 exp)])</div><div>                  ((&gt; (expt d exp) 100) (- (length lst) (length (remove-duplicates lst))))</div><div>                  (for ([i (in-range 2 101)]) (set! lst (cons (* i exp) lst))))))))</div>
</div><div><br></div><div>It solves #2 and #3 above, but it is still fundamentally clunky.</div><div><br></div><div>Can someone help and teach us all some tricks?  My instincts say it should be possible to use append-map, for/list and/or foldl to build a list of the duplicates then simply count them in the for/sum loop, but am still unable to do it.</div>
<div><br></div><div>Thanks,</div><div>-Joe</div>