Hi Guys.<div><br></div><div>Thanks for the education on for/fold and for*/fold.</div><div><br></div><div>Cristian, your solution is very elegant, thanks, but unfortunately it does generate all the numbers so is relatively slow and won't scale too well with a and b. </div>
<div><br></div><div>-Joe<br><br><div class="gmail_quote">On Tue, Apr 17, 2012 at 11:01 AM, Cristian Esquivias <span dir="ltr"><<a href="mailto:cristian.esquivias@gmail.com">cristian.esquivias@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I used Project Euler to try out new languages as well. Here was my<br>
attempt at Problem 29 for reference.<br>
<br>
(define (prob29 a b)<br>
(set-count<br>
(for*/fold<br>
([nums (set)])<br>
([i (in-range 2 (add1 a))]<br>
[j (in-range 2 (add1 b))])<br>
(values (set-add nums (expt i j))))))<br>
<span class="HOEnZb"><font color="#888888"><br>
<br>
- Cristian<br>
</font></span><div class="HOEnZb"><div class="h5"><br>
On Tue, Apr 17, 2012 at 9:54 AM, Matthew Flatt <<a href="mailto:mflatt@cs.utah.edu">mflatt@cs.utah.edu</a>> wrote:<br>
> Blindly refactoring the code, I'd use `for/fold' and add a `lst'<br>
> accumulator to `loop':<br>
><br>
> (define (euler29c)<br>
> ; calculate 99^2 - duplicates<br>
> (- (sqr 99)<br>
> (for/sum ([d '(2 3 5 6 7 10)])<br>
> (let loop ([lst '()] [exp 1])<br>
> (if (> (expt d exp) 100)<br>
> (- (length lst) (length (remove-duplicates lst)))<br>
> (loop (for/fold ([lst lst]) ([i (in-range 2 101)])<br>
> (cons (* i exp) lst))<br>
> (add1 exp)))))))<br>
><br>
> At Tue, 17 Apr 2012 09:45:50 -0700, Joe Gilray wrote:<br>
>> Hi,<br>
>><br>
>> To continue our conversation about creating idiomatic Racket code, here is<br>
>> some code I wrote last night to solve <a href="http://projecteuler.net" target="_blank">projecteuler.net</a> problem #29:<br>
>><br>
>> (define (euler29a)<br>
>> ; calculate 99^2 - duplicates<br>
>> (- (sqr 99)<br>
>> (for/sum ([d '(2 3 5 6 7 10)])<br>
>> (let ([lst '()])<br>
>> (let loop ([exp 1])<br>
>> (if (> (expt d exp) 100) (- (length lst) (length<br>
>> (remove-duplicates lst)))<br>
>> (begin<br>
>> (for ([i (in-range 2 101)]) (set! lst (cons (* i<br>
>> exp) lst)))<br>
>> (loop (add1 exp)))))))))<br>
>><br>
>> It's fast (it avoids calculating a bunch of huge numbers), it gives the<br>
>> correct answer, so what's not to love?!<br>
>><br>
>> Well, it starts off OK, but my eye stumbles over the following:<br>
>><br>
>> 1) predeclaring lst and accessing it twice, related to each other<br>
>> 2) ugly single parameter named-let loop<br>
>> 3) ugly "begin" - not a big deal, but I just dislike when having to use<br>
>> begin<br>
>> 4) use of set!<br>
>><br>
>> Here is a quick rewrite:<br>
>><br>
>> (define (euler29b)<br>
>> ; calculate 99^2 - duplicates<br>
>> (- (sqr 99)<br>
>> (for/sum ([d '(2 3 5 6 7 10)])<br>
>> (let ([lst '()])<br>
>> (do ([exp 1 (add1 exp)])<br>
>> ((> (expt d exp) 100) (- (length lst) (length<br>
>> (remove-duplicates lst))))<br>
>> (for ([i (in-range 2 101)]) (set! lst (cons (* i exp)<br>
>> lst))))))))<br>
>><br>
>> It solves #2 and #3 above, but it is still fundamentally clunky.<br>
>><br>
>> Can someone help and teach us all some tricks? My instincts say it should<br>
>> be possible to use append-map, for/list and/or foldl to build a list of the<br>
>> duplicates then simply count them in the for/sum loop, but am still unable<br>
>> to do it.<br>
>><br>
>> Thanks,<br>
>> -Joe<br>
>> ____________________<br>
>> Racket Users list:<br>
>> <a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/users</a><br>
> ____________________<br>
> Racket Users list:<br>
> <a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/users</a><br>
</div></div></blockquote></div><br></div>