Cristian, One more thing, since for*/fold in your code only takes one accumulator, you don't need "values" at all. Makes the code even shorter!
-Joe On Tue, Apr 17, 2012 at 12:54 PM, Joe Gilray <jgil...@gmail.com> wrote: > Hi Guys. > > Thanks for the education on for/fold and for*/fold. > > 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. > > -Joe > > > On Tue, Apr 17, 2012 at 11:01 AM, Cristian Esquivias < > cristian.esquiv...@gmail.com> wrote: > >> I used Project Euler to try out new languages as well. Here was my >> attempt at Problem 29 for reference. >> >> (define (prob29 a b) >> (set-count >> (for*/fold >> ([nums (set)]) >> ([i (in-range 2 (add1 a))] >> [j (in-range 2 (add1 b))]) >> (values (set-add nums (expt i j)))))) >> >> >> - Cristian >> >> On Tue, Apr 17, 2012 at 9:54 AM, Matthew Flatt <mfl...@cs.utah.edu> >> wrote: >> > Blindly refactoring the code, I'd use `for/fold' and add a `lst' >> > accumulator to `loop': >> > >> > (define (euler29c) >> > ; calculate 99^2 - duplicates >> > (- (sqr 99) >> > (for/sum ([d '(2 3 5 6 7 10)]) >> > (let loop ([lst '()] [exp 1]) >> > (if (> (expt d exp) 100) >> > (- (length lst) (length (remove-duplicates lst))) >> > (loop (for/fold ([lst lst]) ([i (in-range 2 101)]) >> > (cons (* i exp) lst)) >> > (add1 exp))))))) >> > >> > At Tue, 17 Apr 2012 09:45:50 -0700, Joe Gilray wrote: >> >> Hi, >> >> >> >> To continue our conversation about creating idiomatic Racket code, >> here is >> >> some code I wrote last night to solve projecteuler.net problem #29: >> >> >> >> (define (euler29a) >> >> ; calculate 99^2 - duplicates >> >> (- (sqr 99) >> >> (for/sum ([d '(2 3 5 6 7 10)]) >> >> (let ([lst '()]) >> >> (let loop ([exp 1]) >> >> (if (> (expt d exp) 100) (- (length lst) (length >> >> (remove-duplicates lst))) >> >> (begin >> >> (for ([i (in-range 2 101)]) (set! lst (cons (* >> i >> >> exp) lst))) >> >> (loop (add1 exp))))))))) >> >> >> >> It's fast (it avoids calculating a bunch of huge numbers), it gives the >> >> correct answer, so what's not to love?! >> >> >> >> Well, it starts off OK, but my eye stumbles over the following: >> >> >> >> 1) predeclaring lst and accessing it twice, related to each other >> >> 2) ugly single parameter named-let loop >> >> 3) ugly "begin" - not a big deal, but I just dislike when having to use >> >> begin >> >> 4) use of set! >> >> >> >> Here is a quick rewrite: >> >> >> >> (define (euler29b) >> >> ; calculate 99^2 - duplicates >> >> (- (sqr 99) >> >> (for/sum ([d '(2 3 5 6 7 10)]) >> >> (let ([lst '()]) >> >> (do ([exp 1 (add1 exp)]) >> >> ((> (expt d exp) 100) (- (length lst) (length >> >> (remove-duplicates lst)))) >> >> (for ([i (in-range 2 101)]) (set! lst (cons (* i exp) >> >> lst)))))))) >> >> >> >> It solves #2 and #3 above, but it is still fundamentally clunky. >> >> >> >> 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. >> >> >> >> Thanks, >> >> -Joe >> >> ____________________ >> >> Racket Users list: >> >> http://lists.racket-lang.org/users >> > ____________________ >> > Racket Users list: >> > http://lists.racket-lang.org/users >> > >
____________________ Racket Users list: http://lists.racket-lang.org/users