2019-10-18 09:05:06 -04:00
|
|
|
! Copyright (C) 2005, 2007 Slava Pestov.
|
2005-12-31 20:51:58 -05:00
|
|
|
! See http://factorcode.org/license.txt for BSD license.
|
2005-09-10 18:27:31 -04:00
|
|
|
IN: sequences-internals
|
2019-10-18 09:05:06 -04:00
|
|
|
USING: arrays generic kernel kernel-internals math sequences ;
|
2005-09-07 17:21:11 -04:00
|
|
|
|
2019-10-18 09:05:06 -04:00
|
|
|
: (collect) ( n quot accum -- )
|
|
|
|
|
>r over slip r> set-nth-unsafe ; inline
|
2005-12-28 20:25:17 -05:00
|
|
|
|
2019-10-18 09:05:06 -04:00
|
|
|
: collect ( exemplar n quot -- array )
|
|
|
|
|
-rot tuck >r new r>
|
|
|
|
|
[ [ -rot (collect) ] 3keep ] repeat nip ;
|
|
|
|
|
inline
|
|
|
|
|
|
|
|
|
|
: (each) ( seq quot i -- i )
|
|
|
|
|
[ rot nth-unsafe swap call ] 3keep ; inline
|
2005-09-10 18:27:31 -04:00
|
|
|
|
|
|
|
|
: (2each) ( quot seq seq i -- quot seq seq i )
|
|
|
|
|
[ 2nth-unsafe rot dup slip ] 3keep ; inline
|
|
|
|
|
|
|
|
|
|
: (monotonic) ( quot seq i -- ? )
|
2005-09-16 22:47:28 -04:00
|
|
|
2dup 1+ swap nth-unsafe >r swap nth-unsafe r> rot call ;
|
2005-09-10 18:27:31 -04:00
|
|
|
inline
|
|
|
|
|
|
2005-12-28 20:25:17 -05:00
|
|
|
: (interleave) ( n -- array )
|
2006-01-28 15:49:31 -05:00
|
|
|
dup zero? [
|
2005-12-28 20:25:17 -05:00
|
|
|
drop { }
|
|
|
|
|
] [
|
|
|
|
|
t <array> f 0 pick set-nth-unsafe
|
|
|
|
|
] if ;
|
|
|
|
|
|
2019-10-18 09:05:06 -04:00
|
|
|
: find-step [ >r nth-unsafe r> call ] 3keep roll ; inline
|
|
|
|
|
|
|
|
|
|
: find-fails [ 3drop -1 f ] if ; inline
|
|
|
|
|
|
|
|
|
|
: if-bounds+ >r pick pick length < r> find-fails ; inline
|
|
|
|
|
|
|
|
|
|
: if-bounds- >r pick 0 >= r> find-fails ; inline
|
|
|
|
|
|
|
|
|
|
: (find) ( n seq quot -- i elt )
|
|
|
|
|
[
|
|
|
|
|
find-step [
|
|
|
|
|
drop dupd nth-unsafe
|
|
|
|
|
] [
|
|
|
|
|
rot 1+ -rot (find)
|
|
|
|
|
] if
|
|
|
|
|
] if-bounds+ ; inline
|
|
|
|
|
|
|
|
|
|
: (find-last) ( n seq quot -- i elt )
|
|
|
|
|
[
|
|
|
|
|
find-step [
|
|
|
|
|
drop dupd nth-unsafe
|
|
|
|
|
] [
|
|
|
|
|
rot 1- -rot (find-last)
|
|
|
|
|
] if
|
|
|
|
|
] if-bounds- ; inline
|
|
|
|
|
|
|
|
|
|
: (all?) ( n seq quot -- ? )
|
|
|
|
|
pick pick length < [
|
|
|
|
|
find-step [ rot 1+ -rot (all?) ] [ 3drop f ] if
|
|
|
|
|
] [ 3drop t ] if ; inline
|
|
|
|
|
|
|
|
|
|
: change-nth-unsafe ( i seq quot -- )
|
|
|
|
|
[ >r nth-unsafe r> call ] 3keep drop set-nth-unsafe ; inline
|
2019-10-18 09:05:04 -04:00
|
|
|
|
2005-09-10 18:27:31 -04:00
|
|
|
IN: sequences
|
|
|
|
|
|
2006-08-15 16:29:35 -04:00
|
|
|
: each ( seq quot -- )
|
2019-10-18 09:05:06 -04:00
|
|
|
over length [ (each) ] repeat 2drop ; inline
|
2005-09-07 17:21:11 -04:00
|
|
|
|
2006-08-15 16:29:35 -04:00
|
|
|
: each-with ( obj seq quot -- )
|
2005-09-07 17:21:11 -04:00
|
|
|
swap [ with ] each 2drop ; inline
|
|
|
|
|
|
2006-08-15 21:23:05 -04:00
|
|
|
: reduce ( seq identity quot -- result )
|
2005-09-07 17:21:11 -04:00
|
|
|
swapd each ; inline
|
|
|
|
|
|
2019-10-18 09:05:06 -04:00
|
|
|
: map ( seq quot -- newseq )
|
|
|
|
|
over dup length [ (each) drop rot ] collect 2nip ; inline
|
2005-09-07 17:21:11 -04:00
|
|
|
|
2006-08-15 21:23:05 -04:00
|
|
|
: map-with ( obj list quot -- newseq )
|
2005-09-07 17:21:11 -04:00
|
|
|
swap [ with rot ] map 2nip ; inline
|
|
|
|
|
|
2006-08-18 03:16:28 -04:00
|
|
|
: accumulate ( seq identity quot -- final newseq )
|
|
|
|
|
rot [ pick >r swap call r> ] map-with ; inline
|
2005-09-07 17:21:11 -04:00
|
|
|
|
2006-07-28 03:54:46 -04:00
|
|
|
: change-nth ( i seq quot -- )
|
2019-10-18 09:05:06 -04:00
|
|
|
[ >r nth r> call ] 3keep drop set-nth ; inline
|
2006-05-19 21:08:42 -04:00
|
|
|
|
2006-08-15 16:29:35 -04:00
|
|
|
: inject ( seq quot -- )
|
2005-09-10 18:27:31 -04:00
|
|
|
over length
|
2019-10-18 09:05:06 -04:00
|
|
|
[ [ -rot change-nth-unsafe ] 3keep ] repeat 2drop ;
|
2005-09-07 17:21:11 -04:00
|
|
|
inline
|
|
|
|
|
|
2019-10-18 09:05:06 -04:00
|
|
|
: min-length ( seq1 seq2 -- n ) [ length ] 2apply min ; inline
|
2006-07-14 01:00:59 -04:00
|
|
|
|
2019-10-18 09:05:06 -04:00
|
|
|
: max-length ( seq1 seq2 -- n ) [ length ] 2apply max ; inline
|
2005-10-23 18:33:40 -04:00
|
|
|
|
2006-08-15 21:23:05 -04:00
|
|
|
: 2each ( seq1 seq2 quot -- )
|
2005-09-07 18:56:42 -04:00
|
|
|
-rot 2dup min-length [ (2each) ] repeat 3drop ; inline
|
2005-09-07 17:21:11 -04:00
|
|
|
|
2006-08-15 21:23:05 -04:00
|
|
|
: 2reduce ( seq seq identity quot -- result )
|
2005-09-07 17:21:11 -04:00
|
|
|
>r -rot r> 2each ; inline
|
|
|
|
|
|
2006-08-15 21:23:05 -04:00
|
|
|
: 2map ( seq1 seq2 quot -- newseq )
|
2019-10-18 09:05:06 -04:00
|
|
|
-rot 2dup dupd min-length
|
|
|
|
|
[ (2each) drop roll ] collect
|
2005-09-07 18:56:42 -04:00
|
|
|
>r 3drop r> ; inline
|
2005-09-07 17:21:11 -04:00
|
|
|
|
2006-08-15 21:23:05 -04:00
|
|
|
: find* ( n seq quot -- i elt )
|
2019-10-18 09:05:06 -04:00
|
|
|
[ (find) ] if-bounds- ; inline
|
2005-09-07 17:21:11 -04:00
|
|
|
|
2006-08-15 21:23:05 -04:00
|
|
|
: find-with* ( obj n seq quot -- i elt )
|
2005-09-07 17:21:11 -04:00
|
|
|
-rot [ with rot ] find* 2swap 2drop ; inline
|
|
|
|
|
|
2006-08-15 16:29:35 -04:00
|
|
|
: find ( seq quot -- i elt )
|
2019-10-18 09:05:06 -04:00
|
|
|
0 -rot (find) ; inline
|
2006-05-17 14:55:46 -04:00
|
|
|
|
2006-08-15 16:29:35 -04:00
|
|
|
: find-with ( obj seq quot -- i elt )
|
2006-05-17 14:55:46 -04:00
|
|
|
swap [ with rot ] find 2swap 2drop ; inline
|
2005-09-07 17:21:11 -04:00
|
|
|
|
2006-08-15 21:23:05 -04:00
|
|
|
: find-last* ( n seq quot -- i elt )
|
2019-10-18 09:05:06 -04:00
|
|
|
[ (find-last) ] if-bounds+ ; inline
|
2005-10-01 01:44:49 -04:00
|
|
|
|
2006-08-15 21:23:05 -04:00
|
|
|
: find-last-with* ( obj n seq quot -- i elt )
|
2005-10-01 01:44:49 -04:00
|
|
|
-rot [ with rot ] find-last* 2swap 2drop ; inline
|
|
|
|
|
|
|
|
|
|
: find-last ( seq quot -- i elt )
|
2019-10-18 09:05:06 -04:00
|
|
|
>r [ length 1- ] keep r> (find-last) ; inline
|
2005-10-01 01:44:49 -04:00
|
|
|
|
2006-08-15 16:29:35 -04:00
|
|
|
: find-last-with ( obj seq quot -- i elt )
|
2005-11-12 00:37:24 -05:00
|
|
|
swap [ with rot ] find-last 2swap 2drop ; inline
|
|
|
|
|
|
2019-10-18 09:05:06 -04:00
|
|
|
: index ( obj seq -- n )
|
|
|
|
|
[ = ] find-with drop ;
|
|
|
|
|
|
|
|
|
|
: index* ( obj i seq -- n )
|
|
|
|
|
[ = ] find-with* drop ;
|
|
|
|
|
|
|
|
|
|
: last-index ( obj seq -- n )
|
|
|
|
|
[ = ] find-last-with drop ;
|
|
|
|
|
|
|
|
|
|
: last-index* ( obj i seq -- n )
|
|
|
|
|
[ = ] find-last-with* drop ;
|
|
|
|
|
|
2005-09-07 17:21:11 -04:00
|
|
|
: contains? ( seq quot -- ? )
|
|
|
|
|
find drop -1 > ; inline
|
|
|
|
|
|
|
|
|
|
: contains-with? ( obj seq quot -- ? )
|
|
|
|
|
find-with drop -1 > ; inline
|
|
|
|
|
|
2019-10-18 09:05:06 -04:00
|
|
|
: member? ( obj seq -- ? )
|
|
|
|
|
[ = ] contains-with? ;
|
|
|
|
|
|
|
|
|
|
: memq? ( obj seq -- ? )
|
|
|
|
|
[ eq? ] contains-with? ;
|
|
|
|
|
|
2005-09-07 17:21:11 -04:00
|
|
|
: all? ( seq quot -- ? )
|
2019-10-18 09:05:06 -04:00
|
|
|
0 -rot (all?) ; inline
|
2005-09-07 17:21:11 -04:00
|
|
|
|
2006-08-15 16:29:35 -04:00
|
|
|
: all-with? ( obj seq quot -- ? )
|
2005-09-07 17:21:11 -04:00
|
|
|
swap [ with rot ] all? 2nip ; inline
|
|
|
|
|
|
2019-10-18 09:05:06 -04:00
|
|
|
: push-if ( elt quot accum -- )
|
|
|
|
|
>r keep r> rot [ push ] [ 2drop ] if ; inline
|
2019-10-18 09:05:04 -04:00
|
|
|
|
2006-08-15 21:23:05 -04:00
|
|
|
: subset ( seq quot -- subseq )
|
2019-10-18 09:05:06 -04:00
|
|
|
over >r over length pick new-resizable rot
|
|
|
|
|
[ -rot [ push-if ] 2keep ] each
|
|
|
|
|
nip r> like ; inline
|
2005-09-07 17:21:11 -04:00
|
|
|
|
2006-08-15 21:23:05 -04:00
|
|
|
: subset-with ( obj seq quot -- subseq )
|
2005-09-07 17:21:11 -04:00
|
|
|
swap [ with rot ] subset 2nip ; inline
|
|
|
|
|
|
2019-10-18 09:05:06 -04:00
|
|
|
: remove ( obj seq -- newseq )
|
|
|
|
|
[ = not ] subset-with ;
|
|
|
|
|
|
2006-08-15 16:29:35 -04:00
|
|
|
: monotonic? ( seq quot -- ? )
|
2005-09-16 22:47:28 -04:00
|
|
|
swap dup length 1- [
|
2019-10-18 09:05:06 -04:00
|
|
|
[ (monotonic) ] 3keep drop rot
|
2005-09-07 17:21:11 -04:00
|
|
|
] all? 2nip ; inline
|
2005-10-14 04:05:02 -04:00
|
|
|
|
2005-12-28 20:25:17 -05:00
|
|
|
: interleave ( seq quot between -- )
|
|
|
|
|
rot dup length (interleave) [
|
|
|
|
|
[ -rot [ -rot 2slip call ] 2keep ]
|
|
|
|
|
[ -rot [ drop call ] 2keep ]
|
|
|
|
|
if
|
|
|
|
|
] 2each 2drop ; inline
|
|
|
|
|
|
2006-08-15 16:29:35 -04:00
|
|
|
: cache-nth ( i seq quot -- elt )
|
2005-10-14 04:05:02 -04:00
|
|
|
pick pick ?nth dup [
|
|
|
|
|
>r 3drop r>
|
|
|
|
|
] [
|
|
|
|
|
drop swap >r over >r call dup r> r> set-nth
|
|
|
|
|
] if ; inline
|
2006-05-18 22:20:23 -04:00
|
|
|
|
2019-10-18 09:05:06 -04:00
|
|
|
: (mismatch) ( seq1 seq2 n -- i )
|
|
|
|
|
[ >r 2dup r> 2nth-unsafe = not ] find drop 2nip ; inline
|
2006-05-18 22:20:23 -04:00
|
|
|
|
2019-10-18 09:05:06 -04:00
|
|
|
: mismatch ( seq1 seq2 -- i )
|
|
|
|
|
2dup min-length (mismatch) ;
|
2006-05-18 22:20:23 -04:00
|
|
|
|
2019-10-18 09:05:06 -04:00
|
|
|
: sequence= ( seq1 seq2 -- ? )
|
|
|
|
|
2dup [ length ] 2apply tuck number=
|
|
|
|
|
[ (mismatch) -1 number= ] [ 3drop f ] if ; inline
|