[racket] making Racket code more idiomatic
Thanks for more food for thought.
Cristian, I really like the form of your solution with the answer being
produced at the bottom. You also taught me about stop-before and
stop-after. Very nice.
Maxim, Thanks for bringing up for*/set. Your solution is elegant, but
unfortunately is relatively slow because it calculates all the numbers and
so doesn't scale very well with a and b (try upper = 1000).
Here's Cristian's code scaled to 400. It runs in under .1 seconds:
(define (euler29d)
(- (sqr 999)
(for/sum ([base '(2 3 5 6 7 10 11 12 13 14 15 17 18 19 20)])
(define lst
(for*/list ([exp (stop-before (in-naturals 1) (λ (exp) (>
(expt base exp) 400)))]
[i (in-range 2 401)]) (* i exp)))
(- (length lst) (length (remove-duplicates lst))))))
On Wed, Apr 18, 2012 at 5:33 AM, Maxim Romashchenko <max at anahoret.com>wrote:
> What about for*/set ?
>
> #lang racket
> (require racket/set)
> (define (generate-powers lower upper)
> (for*/set ([a (in-range lower (add1 upper))]
> [b (in-range lower (add1 upper))])
> (expt a b)))
> (set-count (generate-powers 2 5))
> (set-count (generate-powers 2 100))
>
> Best regards, Maxim.
>
>
>
> On 2012-04-17 21:01, Cristian Esquivias 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<http://lists.racket-lang.org/users>
>>>>
>>> ____________________
>>> Racket Users list:
>>> http://lists.racket-lang.org/**users<http://lists.racket-lang.org/users>
>>>
>>
>> ____________________
>> Racket Users list:
>> http://lists.racket-lang.org/**users<http://lists.racket-lang.org/users>
>>
> ____________________
> Racket Users list:
> http://lists.racket-lang.org/**users <http://lists.racket-lang.org/users>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20120418/cb3efde0/attachment-0001.html>