[racket] making Racket code more idiomatic
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 <jgilray at 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.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/60d61af8/attachment.html>