Re: [racket-users] Re: how to make a cartesian supergenerator?

2018-10-21 Thread Robby Findler
If I am understanding this right, data/enumerate's list/e combinator doing
a similar job. It might also be helpful.

Robby

On Sun, Oct 21, 2018 at 5:50 PM Jay McCarthy  wrote:

> I think the best strategy would be to convert the generator to a
> sequence and then the sequence to a stream, then write a stream
> cartesian product. The stream will cache the results of the generator.
> On Sun, Oct 21, 2018 at 4:58 PM Matthew Butterick  wrote:
> >
> > I suppose just putting in a hash isn't too bad.
> >
> > #lang racket
> > (require racket/generator rackunit)
> >
> > (define/contract (make-cartesian-generator gens)
> >   ((listof generator?) . -> . generator?)
> >   (generator ()
> >  (define solcache (make-hasheqv))
> >  (let loop ([gens gens][genidx 0][sols empty])
> >(cond
> >  [(empty? gens) (yield (reverse sols))]
> >  [else
> >   (match-define (cons gen rest) gens)
> >   (cond
> > [(eq? (generator-state gen) 'done)
> >  (for ([sol (in-list (reverse (hash-ref solcache
> genidx)))])
> >(loop rest (add1 genidx) (cons sol sols)))]
> > [else
> >  (for ([sol (in-producer gen (void))])
> >(hash-update! solcache genidx (λ (vals) (cons sol
> vals)) null)
> >(loop rest (add1 genidx) (cons sol sols)))])]
> >
> > (define g1 (generator () (yield 1) (yield 2) (void)))
> > (define g2 (generator () (yield 'a) (yield 'b) (void)))
> >
> > (check-equal?
> >  (for/list ([gs (in-producer (make-cartesian-generator (list g1 g2))
> (void))])
> >gs)
> >  '((1 a) (1 b) (2 a) (2 b)))
> >
> > --
> > You received this message because you are subscribed to the Google
> Groups "Racket Users" group.
> > To unsubscribe from this group and stop receiving emails from it, send
> an email to racket-users+unsubscr...@googlegroups.com.
> > For more options, visit https://groups.google.com/d/optout.
>
>
>
> --
> -=[ Jay McCarthy   http://jeapostrophe.github.io]=-
> -=[ Associate ProfessorPLT @ CS @ UMass Lowell ]=-
> -=[ Moses 1:33: And worlds without number have I created; ]=-
>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Re: how to make a cartesian supergenerator?

2018-10-21 Thread Jay McCarthy
I think the best strategy would be to convert the generator to a
sequence and then the sequence to a stream, then write a stream
cartesian product. The stream will cache the results of the generator.
On Sun, Oct 21, 2018 at 4:58 PM Matthew Butterick  wrote:
>
> I suppose just putting in a hash isn't too bad.
>
> #lang racket
> (require racket/generator rackunit)
>
> (define/contract (make-cartesian-generator gens)
>   ((listof generator?) . -> . generator?)
>   (generator ()
>  (define solcache (make-hasheqv))
>  (let loop ([gens gens][genidx 0][sols empty])
>(cond
>  [(empty? gens) (yield (reverse sols))]
>  [else
>   (match-define (cons gen rest) gens)
>   (cond
> [(eq? (generator-state gen) 'done)
>  (for ([sol (in-list (reverse (hash-ref solcache 
> genidx)))])
>(loop rest (add1 genidx) (cons sol sols)))]
> [else
>  (for ([sol (in-producer gen (void))])
>(hash-update! solcache genidx (λ (vals) (cons sol 
> vals)) null)
>(loop rest (add1 genidx) (cons sol sols)))])]
>
> (define g1 (generator () (yield 1) (yield 2) (void)))
> (define g2 (generator () (yield 'a) (yield 'b) (void)))
>
> (check-equal?
>  (for/list ([gs (in-producer (make-cartesian-generator (list g1 g2)) (void))])
>gs)
>  '((1 a) (1 b) (2 a) (2 b)))
>
> --
> You received this message because you are subscribed to the Google Groups 
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.



-- 
-=[ Jay McCarthy   http://jeapostrophe.github.io]=-
-=[ Associate ProfessorPLT @ CS @ UMass Lowell ]=-
-=[ Moses 1:33: And worlds without number have I created; ]=-

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Re: how to make a cartesian supergenerator?

2018-10-21 Thread Matthew Butterick
I suppose just putting in a hash isn't too bad. 

#lang racket
(require racket/generator rackunit)

(define/contract (make-cartesian-generator gens)
  ((listof generator?) . -> . generator?)
  (generator ()
 (define solcache (make-hasheqv))
 (let loop ([gens gens][genidx 0][sols empty])
   (cond
 [(empty? gens) (yield (reverse sols))]
 [else 
  (match-define (cons gen rest) gens)
  (cond
[(eq? (generator-state gen) 'done)
 (for ([sol (in-list (reverse (hash-ref solcache genidx)))])
   (loop rest (add1 genidx) (cons sol sols)))]
[else
 (for ([sol (in-producer gen (void))])
   (hash-update! solcache genidx (λ (vals) (cons sol vals)) 
null)
   (loop rest (add1 genidx) (cons sol sols)))])]

(define g1 (generator () (yield 1) (yield 2) (void)))
(define g2 (generator () (yield 'a) (yield 'b) (void)))

(check-equal? 
 (for/list ([gs (in-producer (make-cartesian-generator (list g1 g2)) (void))])
   gs)
 '((1 a) (1 b) (2 a) (2 b)))

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.