2005-09-10 18:27:31 -04:00
|
|
|
IN: sequences-internals
|
2006-01-09 01:34:23 -05:00
|
|
|
USING: arrays generic kernel math sequences ;
|
2005-08-13 23:39:46 -04:00
|
|
|
|
2005-09-10 18:27:31 -04:00
|
|
|
: midpoint@ length 2 /i ; inline
|
|
|
|
|
|
|
|
: midpoint [ midpoint@ ] keep nth-unsafe ; inline
|
|
|
|
|
2005-08-22 15:33:18 -04:00
|
|
|
TUPLE: sorter seq start end mid ;
|
2005-08-22 01:17:08 -04:00
|
|
|
|
|
|
|
C: sorter ( seq start end -- sorter )
|
2005-09-16 22:47:28 -04:00
|
|
|
[ >r 1+ rot <slice> r> set-sorter-seq ] keep
|
2005-08-22 01:17:08 -04:00
|
|
|
dup sorter-seq midpoint over set-sorter-mid
|
2005-09-16 22:47:28 -04:00
|
|
|
dup sorter-seq length 1- over set-sorter-end
|
2005-08-22 20:54:01 -04:00
|
|
|
0 over set-sorter-start ; inline
|
2005-08-22 01:17:08 -04:00
|
|
|
|
2005-08-22 20:54:01 -04:00
|
|
|
: s*/e* dup sorter-start swap sorter-end ; inline
|
2005-09-16 22:47:28 -04:00
|
|
|
: s*/e dup sorter-start swap sorter-seq length 1- ; inline
|
2005-08-22 20:54:01 -04:00
|
|
|
: s/e* 0 swap sorter-end ; inline
|
2006-03-14 16:51:09 -05:00
|
|
|
: sorter-exchange dup s*/e* rot sorter-seq exchange-unsafe ; inline
|
2005-09-10 18:27:31 -04:00
|
|
|
: compare over sorter-seq nth-unsafe swap sorter-mid rot call ; inline
|
2005-09-16 22:47:28 -04:00
|
|
|
: >start> dup sorter-start 1+ swap set-sorter-start ; inline
|
|
|
|
: <end< dup sorter-end 1- swap set-sorter-end ; inline
|
2005-08-22 01:17:08 -04:00
|
|
|
|
|
|
|
: sort-up ( quot sorter -- quot sorter )
|
|
|
|
dup s*/e < [
|
|
|
|
[ dup sorter-start compare 0 < ] 2keep rot
|
|
|
|
[ dup >start> sort-up ] when
|
|
|
|
] when ; inline
|
|
|
|
|
|
|
|
: sort-down ( quot sorter -- quot sorter )
|
2005-09-24 16:34:10 -04:00
|
|
|
dup s/e* < [
|
2005-08-22 01:17:08 -04:00
|
|
|
[ dup sorter-end compare 0 > ] 2keep rot
|
|
|
|
[ dup <end< sort-down ] when
|
|
|
|
] when ; inline
|
|
|
|
|
|
|
|
: sort-step ( quot sorter -- quot sorter )
|
|
|
|
dup s*/e* <= [
|
|
|
|
sort-up sort-down dup s*/e* <= [
|
|
|
|
dup sorter-exchange dup >start> dup <end< sort-step
|
|
|
|
] when
|
|
|
|
] when ; inline
|
|
|
|
|
|
|
|
: (nsort) ( quot seq start end -- )
|
|
|
|
2dup < [
|
|
|
|
<sorter> sort-step
|
|
|
|
[ dup sorter-seq swap s/e* (nsort) ] 2keep
|
|
|
|
[ dup sorter-seq swap s*/e (nsort) ] 2keep
|
2005-08-13 23:39:46 -04:00
|
|
|
] [
|
|
|
|
2drop
|
2005-09-24 15:21:17 -04:00
|
|
|
] if 2drop ; inline
|
2005-08-13 23:39:46 -04:00
|
|
|
|
2005-08-22 20:54:01 -04:00
|
|
|
: partition ( -1/1 seq -- seq )
|
|
|
|
dup midpoint@ swap rot 1 <
|
2005-09-24 15:21:17 -04:00
|
|
|
[ head-slice ] [ tail-slice ] if ; inline
|
2005-08-22 17:40:44 -04:00
|
|
|
|
|
|
|
: (binsearch) ( elt quot seq -- i )
|
|
|
|
dup length 1 <= [
|
|
|
|
2nip slice-from
|
|
|
|
] [
|
2006-01-28 15:49:31 -05:00
|
|
|
3dup >r >r >r midpoint swap call dup zero? [
|
2005-08-22 20:54:01 -04:00
|
|
|
r> r> 3drop r> dup slice-from swap slice-to + 2 /i
|
2005-08-22 17:40:44 -04:00
|
|
|
] [
|
2005-08-22 20:54:01 -04:00
|
|
|
r> swap r> swap r> partition (binsearch)
|
2005-09-24 15:21:17 -04:00
|
|
|
] if
|
|
|
|
] if ; inline
|
2005-08-22 17:40:44 -04:00
|
|
|
|
2005-08-24 19:25:12 -04:00
|
|
|
: flatten-slice ( seq -- slice )
|
2005-08-22 17:40:44 -04:00
|
|
|
#! Binsearch returns an index relative to the sequence
|
|
|
|
#! being sliced, so if we are given a slice as input,
|
|
|
|
#! unexpected behavior will result.
|
2005-09-11 21:18:19 -04:00
|
|
|
dup slice? [ >array ] when 0 over length rot <slice> ;
|
2005-08-22 17:40:44 -04:00
|
|
|
inline
|
|
|
|
|
2005-08-13 23:39:46 -04:00
|
|
|
IN: sequences
|
|
|
|
|
|
|
|
: nsort ( seq quot -- | quot: elt elt -- -1/0/1 )
|
2005-08-23 15:50:32 -04:00
|
|
|
swap dup length 1 <=
|
2005-09-24 15:21:17 -04:00
|
|
|
[ 2drop ] [ 0 over length 1- (nsort) ] if ; inline
|
2005-08-13 23:39:46 -04:00
|
|
|
|
|
|
|
: sort ( seq quot -- seq | quot: elt elt -- -1/0/1 )
|
|
|
|
swap [ swap nsort ] immutable ; inline
|
2005-08-22 17:40:44 -04:00
|
|
|
|
2006-01-09 01:34:23 -05:00
|
|
|
: natural-sort ( seq -- seq ) [ <=> ] sort ;
|
2005-08-24 10:19:09 -04:00
|
|
|
|
2005-08-22 17:40:44 -04:00
|
|
|
: binsearch ( elt seq quot -- i | quot: elt elt -- -1/0/1 )
|
|
|
|
swap dup empty?
|
2005-09-24 16:34:10 -04:00
|
|
|
[ 3drop -1 ] [ flatten-slice (binsearch) ] if ; inline
|
2005-08-23 23:28:54 -04:00
|
|
|
|
|
|
|
: binsearch* ( elt seq quot -- elt | quot: elt elt -- -1/0/1 )
|
2005-09-24 15:21:17 -04:00
|
|
|
over >r binsearch dup -1 = [ r> 2drop f ] [ r> nth ] if ;
|
2005-08-23 23:28:54 -04:00
|
|
|
inline
|