[racket] making Racket code more idiomatic
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.esquivias at 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 <mflatt at 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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20120417/779a29f8/attachment-0001.html>