Oops: I had scaled it to 1000 (also runs in under .1 seconds). Here is the right code:
(define (euler29d) (- (sqr 399) (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)))))) 2012/4/18 Joe Gilray <jgil...@gmail.com> > 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 <m...@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<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<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> >> > >
____________________ Racket Users list: http://lists.racket-lang.org/users