factor/basis/sequences/product/product.factor

80 lines
2.3 KiB
Factor
Raw Normal View History

2009-04-26 14:09:30 -04:00
! (c)2009 Joe Groff bsd license
USING: accessors arrays assocs kernel locals math sequences
sequences.private ;
2009-04-26 10:39:38 -04:00
IN: sequences.product
TUPLE: product-sequence { sequences array read-only } { lengths array read-only } ;
: <product-sequence> ( sequences -- product-sequence )
>array dup [ length ] map product-sequence boa ;
INSTANCE: product-sequence sequence
M: product-sequence length lengths>> product ;
<PRIVATE
2009-04-26 10:39:38 -04:00
: ns ( n lengths -- ns )
2010-10-19 12:03:05 -04:00
[ /mod ] map nip ;
2009-04-26 10:39:38 -04:00
: nths ( ns seqs -- nths )
[ nth ] { } 2map-as ;
2009-04-26 10:39:38 -04:00
: product@ ( n product-sequence -- ns seqs )
[ lengths>> ns ] [ nip sequences>> ] 2bi ;
:: (carry-n) ( ns lengths i -- )
ns length i 1 + = [
i ns nth-unsafe i lengths nth-unsafe = [
0 i ns set-nth-unsafe
i 1 + ns [ 1 + ] change-nth-unsafe
ns lengths i 1 + (carry-n)
] when
] unless ; inline recursive
: carry-ns ( ns lengths -- )
0 (carry-n) ; inline
2011-09-22 20:19:51 -04:00
: product-iter ( ns lengths -- )
[ 0 over [ 1 + ] change-nth-unsafe ] dip carry-ns ; inline
: start-product-iter ( sequences -- ns lengths )
[ length 0 <array> ] [ [ length ] map ] bi ; inline
: end-product-iter? ( ns lengths -- ? )
[ last-unsafe ] same? ; inline
: product-length ( sequences -- length )
[ length ] [ * ] map-reduce ; inline
PRIVATE>
2011-09-22 20:19:51 -04:00
M: product-sequence nth
product@ nths ;
:: product-each ( ... sequences quot: ( ... seq -- ... ) -- ... )
sequences start-product-iter :> ( ns lengths )
lengths [ 0 = ] any? [
[ ns lengths end-product-iter? ]
[ ns sequences nths quot call ns lengths product-iter ] until
] unless ; inline
2009-04-26 10:39:38 -04:00
:: product-map-as ( ... sequences quot: ( ... seq -- ... value ) exemplar -- ... sequence )
0 :> i!
sequences product-length exemplar
[| result |
sequences [ quot call i result set-nth-unsafe i 1 + i! ] product-each
result
] new-like ; inline
2009-04-26 10:39:38 -04:00
: product-map ( ... sequences quot: ( ... seq -- ... value ) -- ... sequence )
over product-map-as ; inline
2009-11-27 23:58:17 -05:00
:: product-map>assoc ( ... sequences quot: ( ... seq -- ... key value ) exemplar -- ... assoc )
2009-11-27 23:58:17 -05:00
0 :> i!
sequences product-length { }
2009-11-27 23:58:17 -05:00
[| result |
sequences [ quot call 2array i result set-nth-unsafe i 1 + i! ] product-each
2009-11-27 23:58:17 -05:00
result
] new-like exemplar assoc-like ; inline