utils: Add cartesian-product-2/stream.

This commit is contained in:
Sergiu Ivanov 2022-03-04 17:24:18 +01:00
parent 3918730e1a
commit 8cd75b0fa3
2 changed files with 47 additions and 2 deletions

View file

@ -427,6 +427,26 @@ range @racket[min] to @racket[max]-1.}
(stream->list (stream-take (in-random 5 10) 5)) (stream->list (stream-take (in-random 5 10) 5))
]} ]}
@defproc[(cartesian-product-2/stream [s1 (Sequenceof a)]
[s2 (Sequenceof b)])
(Sequenceof (Pair a b))]{
Generates a stream containing all the pairs of the elements from @racket[s1]
and @racket[s2]. The elements of @racket[s2] are enumerated in order for every
element of the @racket[s1], taken in order as well.
@examples[#:eval utils-evaluator
(require typed/racket/stream)
(stream->list (cartesian-product-2/stream (in-range 1 5) '(a b)))
]
The streams can be infinite. If the second stream is infinite, only the first
element of @racket[s1] will be enumerated.
@examples[#:eval utils-evaluator
(stream->list (stream-take (cartesian-product-2/stream '(a b) (in-naturals)) 10))
]}
@section{Functions and procedures} @section{Functions and procedures}
@section{Randomness} @section{Randomness}

View file

@ -24,7 +24,7 @@
list-sets->list-strings pretty-print-set pretty-print-set-sets list-sets->list-strings pretty-print-set pretty-print-set-sets
update-vertices/unweighted update-graph dotit collect-by-key update-vertices/unweighted update-graph dotit collect-by-key
collect-by-key/sets ht-values/list->set hash->list/ordered collect-by-key/sets ht-values/list->set hash->list/ordered
multi-split-at lists-transpose in-random) multi-split-at lists-transpose in-random cartesian-product-2/stream)
(define-type Variable Symbol) (define-type Variable Symbol)
(define-type (VariableMapping A) (Immutable-HashTable Variable A)) (define-type (VariableMapping A) (Immutable-HashTable Variable A))
@ -475,6 +475,31 @@
0.22552976312818723 0.22552976312818723
0.21646500425988832 0.21646500425988832
0.15188352823997242)))) 0.15188352823997242))))
(: cartesian-product-2/stream (All (a b) (-> (Sequenceof a) (Sequenceof b) (Sequenceof (Pair a b)))))
(define (cartesian-product-2/stream s1 s2)
(: cp2-store (All (a b) (-> (Sequenceof a) (Sequenceof b) (Sequenceof b)
(Sequenceof (Pair a b)))))
;; The recursive implementation using s2-store as an accumulator.
;; Main idea: combine the elements of s1 with the element of s2
;; until they are exhausted, then restart with the next element of
;; s1 and the original content of s2.
(define (cp2-store s1 s2 s2-store)
(cond
[(stream-empty? s1) (stream)]
[(stream-empty? s2) (cp2-store (stream-rest s1) s2-store s2-store)]
[else
(stream-cons (cons (stream-first s1) (stream-first s2))
(cp2-store s1 (stream-rest s2) s2-store))]))
(cp2-store s1 s2 s2))
(module+ test
(test-case "cartesian-product-2/stream"
(check-equal? (stream->list (cartesian-product-2/stream (in-range 1 5) '(a b)))
'((1 . a) (1 . b) (2 . a) (2 . b) (3 . a) (3 . b) (4 . a) (4 . b)))
(check-equal?
(stream->list (stream-take (cartesian-product-2/stream '(a b) (in-naturals)) 10))
'((a . 0) (a . 1) (a . 2) (a . 3) (a . 4) (a . 5) (a . 6) (a . 7) (a . 8) (a . 9)))))
) )
(require 'typed) (require 'typed)
@ -485,7 +510,7 @@
list-sets->list-strings pretty-print-set pretty-print-set-sets list-sets->list-strings pretty-print-set pretty-print-set-sets
update-vertices/unweighted update-graph dotit collect-by-key update-vertices/unweighted update-graph dotit collect-by-key
collect-by-key/sets ht-values/list->set hash->list/ordered collect-by-key/sets ht-values/list->set hash->list/ordered
multi-split-at lists-transpose in-random) multi-split-at lists-transpose in-random cartesian-product-2/stream)
;;; Untyped section. ;;; Untyped section.