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<[email protected]>  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
____________________
 Racket Users list:
 http://lists.racket-lang.org/users

Reply via email to