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