2008-02-11 01:14:40 -05:00
|
|
|
! Copyright (C) 2007 Slava Pestov, Chris Double, Doug Coleman,
|
|
|
|
! Eduardo Cavazos, Daniel Ehrenberg.
|
|
|
|
! See http://factorcode.org/license.txt for BSD license.
|
2007-12-08 00:16:26 -05:00
|
|
|
USING: combinators.lib kernel sequences math namespaces assocs
|
2008-02-01 19:26:32 -05:00
|
|
|
random sequences.private shuffle math.functions mirrors
|
2008-02-11 02:19:53 -05:00
|
|
|
arrays math.parser sorting strings ascii macros ;
|
2007-09-20 18:09:08 -04:00
|
|
|
IN: sequences.lib
|
|
|
|
|
2008-02-11 01:14:40 -05:00
|
|
|
: each-withn ( seq quot n -- ) nwith each ; inline
|
|
|
|
|
|
|
|
: each-with ( seq quot -- ) with each ; inline
|
|
|
|
|
|
|
|
: each-with2 ( obj obj list quot -- ) 2 each-withn ; inline
|
|
|
|
|
|
|
|
: map-withn ( seq quot n -- newseq ) nwith map ; inline
|
|
|
|
|
|
|
|
: map-with ( seq quot -- ) with map ; inline
|
|
|
|
|
|
|
|
: map-with2 ( obj obj list quot -- newseq ) 2 map-withn ; inline
|
|
|
|
|
|
|
|
MACRO: nfirst ( n -- )
|
|
|
|
[ [ swap nth ] curry [ keep ] curry ] map concat [ drop ] compose ;
|
|
|
|
|
|
|
|
: prepare-index ( seq quot -- seq n quot )
|
|
|
|
>r dup length r> ; inline
|
|
|
|
|
|
|
|
: each-index ( seq quot -- )
|
|
|
|
#! quot: ( elt index -- )
|
|
|
|
prepare-index 2each ; inline
|
|
|
|
|
|
|
|
: map-index ( seq quot -- )
|
|
|
|
#! quot: ( elt index -- obj )
|
|
|
|
prepare-index 2map ; inline
|
|
|
|
|
|
|
|
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
|
|
|
|
|
|
: sigma ( seq quot -- n )
|
|
|
|
[ rot slip + ] curry 0 swap reduce ; inline
|
|
|
|
|
|
|
|
: count ( seq quot -- n )
|
|
|
|
[ 1 0 ? ] compose sigma ; inline
|
|
|
|
|
2007-09-20 18:09:08 -04:00
|
|
|
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
|
|
|
|
|
|
: map-reduce ( seq map-quot reduce-quot -- result )
|
|
|
|
>r [ unclip ] dip [ call ] keep r> compose reduce ; inline
|
|
|
|
|
|
|
|
: reduce* ( seq quot -- result ) [ ] swap map-reduce ; inline
|
|
|
|
|
|
|
|
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
|
|
|
|
|
|
: higher ( a b quot -- c ) [ compare 0 > ] curry most ; inline
|
|
|
|
|
|
|
|
: lower ( a b quot -- c ) [ compare 0 < ] curry most ; inline
|
|
|
|
|
|
|
|
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
|
|
|
|
|
|
: longer ( a b -- c ) [ length ] higher ;
|
|
|
|
|
|
|
|
: shorter ( a b -- c ) [ length ] lower ;
|
|
|
|
|
|
|
|
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
|
|
|
|
|
|
: longest ( seq -- item ) [ longer ] reduce* ;
|
|
|
|
|
|
|
|
: shortest ( seq -- item ) [ shorter ] reduce* ;
|
|
|
|
|
|
|
|
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
|
|
|
|
|
|
: bigger ( a b -- c ) [ ] higher ;
|
|
|
|
|
|
|
|
: smaller ( a b -- c ) [ ] lower ;
|
|
|
|
|
|
|
|
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
|
|
|
|
|
|
: biggest ( seq -- item ) [ bigger ] reduce* ;
|
|
|
|
|
|
|
|
: smallest ( seq -- item ) [ smaller ] reduce* ;
|
|
|
|
|
|
|
|
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
|
|
|
|
|
|
: minmax ( seq -- min max )
|
|
|
|
#! find the min and max of a seq in one pass
|
|
|
|
1/0. -1/0. rot [ tuck max >r min r> ] each ;
|
|
|
|
|
2007-10-31 17:02:47 -04:00
|
|
|
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
|
|
|
|
|
|
: ,, building get peek push ;
|
|
|
|
: v, V{ } clone , ;
|
|
|
|
: ,v building get dup peek empty? [ dup pop* ] when drop ;
|
|
|
|
|
|
|
|
: monotonic-split ( seq quot -- newseq )
|
|
|
|
[
|
|
|
|
>r dup unclip add r>
|
|
|
|
v, [ pick ,, call [ v, ] unless ] curry 2each ,v
|
|
|
|
] { } make ;
|
|
|
|
|
|
|
|
: singleton? ( seq -- ? )
|
2008-01-13 15:33:36 -05:00
|
|
|
length 1 = ;
|
2007-10-31 17:02:47 -04:00
|
|
|
|
2007-11-05 02:50:19 -05:00
|
|
|
: delete-random ( seq -- value )
|
|
|
|
[ length random ] keep [ nth ] 2keep delete-nth ;
|
2007-11-30 21:01:59 -05:00
|
|
|
|
2007-11-30 23:22:08 -05:00
|
|
|
: split-around ( seq quot -- before elem after )
|
|
|
|
dupd find over [ "Element not found" throw ] unless
|
2008-02-11 01:14:40 -05:00
|
|
|
>r cut 1 tail r> swap ; inline
|
2007-12-19 12:40:55 -05:00
|
|
|
|
2007-11-30 21:23:27 -05:00
|
|
|
: (map-until) ( quot pred -- quot )
|
2007-11-30 21:01:59 -05:00
|
|
|
[ dup ] swap 3compose
|
|
|
|
[ [ drop t ] [ , f ] if ] compose [ find 2drop ] curry ;
|
|
|
|
|
2007-11-30 21:23:27 -05:00
|
|
|
: map-until ( seq quot pred -- newseq )
|
2007-11-30 21:01:59 -05:00
|
|
|
(map-until) { } make ;
|
2007-11-30 21:23:27 -05:00
|
|
|
|
|
|
|
: take-while ( seq quot -- newseq )
|
|
|
|
[ not ] compose
|
|
|
|
[ find drop [ head-slice ] when* ] curry
|
|
|
|
[ dup ] swap compose keep like ;
|
2007-12-08 00:16:26 -05:00
|
|
|
|
|
|
|
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
|
|
|
|
|
|
<PRIVATE
|
|
|
|
: translate-string ( n alphabet out-len -- seq )
|
2008-01-09 17:36:30 -05:00
|
|
|
[ drop /mod ] with map nip ;
|
2007-12-08 00:16:26 -05:00
|
|
|
|
|
|
|
: map-alphabet ( alphabet seq[seq] -- seq[seq] )
|
2008-01-09 17:36:30 -05:00
|
|
|
[ [ swap nth ] with map ] with map ;
|
2007-12-08 00:16:26 -05:00
|
|
|
|
|
|
|
: exact-number-strings ( n out-len -- seqs )
|
|
|
|
[ ^ ] 2keep [ translate-string ] 2curry map ;
|
|
|
|
|
|
|
|
: number-strings ( n max-length -- seqs )
|
2008-01-09 17:36:30 -05:00
|
|
|
1+ [ exact-number-strings ] with map concat ;
|
2007-12-08 00:16:26 -05:00
|
|
|
PRIVATE>
|
|
|
|
|
|
|
|
: exact-strings ( alphabet length -- seqs )
|
|
|
|
>r dup length r> exact-number-strings map-alphabet ;
|
|
|
|
|
|
|
|
: strings ( alphabet length -- seqs )
|
|
|
|
>r dup length r> number-strings map-alphabet ;
|
|
|
|
|
|
|
|
: nths ( nths seq -- subseq )
|
|
|
|
! nths is a sequence of ones and zeroes
|
|
|
|
>r [ length ] keep [ nth 1 = ] curry subset r>
|
|
|
|
[ nth ] curry { } map-as ;
|
|
|
|
|
|
|
|
: power-set ( seq -- subsets )
|
|
|
|
2 over length exact-number-strings swap [ nths ] curry map ;
|
2007-12-16 20:34:44 -05:00
|
|
|
|
|
|
|
: push-either ( elt quot accum1 accum2 -- )
|
|
|
|
>r >r keep swap r> r> ? push ; inline
|
|
|
|
|
|
|
|
: 2pusher ( quot -- quot accum1 accum2 )
|
|
|
|
V{ } clone V{ } clone [ [ push-either ] 3curry ] 2keep ; inline
|
|
|
|
|
|
|
|
: partition ( seq quot -- trueseq falseseq )
|
|
|
|
over >r 2pusher >r >r each r> r> r> drop ; inline
|
2008-01-06 12:30:23 -05:00
|
|
|
|
2007-12-18 03:37:06 -05:00
|
|
|
: cut-find ( seq pred -- before after )
|
|
|
|
dupd find drop dup [ cut ] when ;
|
|
|
|
|
|
|
|
: cut3 ( seq pred -- first mid last )
|
|
|
|
[ cut-find ] keep [ not ] compose cut-find ;
|
|
|
|
|
|
|
|
: (cut-all) ( seq pred quot -- )
|
|
|
|
[ >r cut3 r> dip >r >r , r> [ , ] when* r> ] 2keep
|
|
|
|
pick [ (cut-all) ] [ 3drop ] if ;
|
|
|
|
|
|
|
|
: cut-all ( seq pred quot -- first mid last )
|
|
|
|
[ (cut-all) ] { } make ;
|
|
|
|
|
|
|
|
: human-sort ( seq -- newseq )
|
|
|
|
[ dup [ digit? ] [ string>number ] cut-all ] { } map>assoc
|
|
|
|
sort-values keys ;
|
2007-12-27 17:38:54 -05:00
|
|
|
|
|
|
|
: ?first ( seq -- first/f ) 0 swap ?nth ; inline
|
|
|
|
: ?second ( seq -- second/f ) 1 swap ?nth ; inline
|
|
|
|
: ?third ( seq -- third/f ) 2 swap ?nth ; inline
|
|
|
|
: ?fourth ( seq -- fourth/f ) 3 swap ?nth ; inline
|
2008-02-01 23:46:32 -05:00
|
|
|
|
|
|
|
: accumulator ( quot -- quot vec )
|
|
|
|
V{ } clone [ [ push ] curry compose ] keep ;
|
2008-02-03 17:06:36 -05:00
|
|
|
|
2008-02-03 04:48:58 -05:00
|
|
|
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
|
|
|
|
|
|
! List the positions of obj in seq
|
|
|
|
|
|
|
|
: indices ( seq obj -- seq )
|
2008-02-11 01:14:40 -05:00
|
|
|
>r dup length swap r>
|
|
|
|
[ = [ ] [ drop f ] if ] curry
|
|
|
|
2map
|
|
|
|
[ ] subset ;
|