| 
									
										
										
										
											2009-03-12 21:43:44 -04:00
										 |  |  | ! Copyright (C) 2008, 2009 Slava Pestov. | 
					
						
							| 
									
										
										
										
											2008-07-15 18:16:08 -04:00
										 |  |  | ! See http://factorcode.org/license.txt for BSD license. | 
					
						
							|  |  |  | USING: kernel sequences sequences.private accessors math | 
					
						
							| 
									
										
										
										
											2008-08-24 04:59:37 -04:00
										 |  |  | math.order combinators hints arrays ;
 | 
					
						
							| 
									
										
										
										
											2008-07-15 18:16:08 -04:00
										 |  |  | IN: binary-search | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <PRIVATE
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : midpoint ( seq -- elt )
 | 
					
						
							|  |  |  |     [ midpoint@ ] keep nth-unsafe ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : decide ( quot seq -- quot seq <=> )
 | 
					
						
							|  |  |  |     [ midpoint swap call ] 2keep rot ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : finish ( quot slice -- i elt )
 | 
					
						
							|  |  |  |     [ [ from>> ] [ midpoint@ ] bi + ] [ seq>> ] bi
 | 
					
						
							|  |  |  |     [ drop ] [ dup ] [ ] tri* nth ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-12 21:43:44 -04:00
										 |  |  | DEFER: (search) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : keep-searching ( seq quot -- slice )
 | 
					
						
							|  |  |  |     [ dup midpoint@ ] dip call collapse-slice slice boa (search) ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-18 20:22:59 -04:00
										 |  |  | : (search) ( quot: ( elt -- <=> ) seq -- i elt )
 | 
					
						
							| 
									
										
										
										
											2008-07-15 18:16:08 -04:00
										 |  |  |     dup length 1 <= [ | 
					
						
							|  |  |  |         finish | 
					
						
							|  |  |  |     ] [ | 
					
						
							|  |  |  |         decide { | 
					
						
							|  |  |  |             { +eq+ [ finish ] } | 
					
						
							| 
									
										
										
										
											2009-03-12 21:43:44 -04:00
										 |  |  |             { +lt+ [ [ (head) ] keep-searching ] } | 
					
						
							|  |  |  |             { +gt+ [ [ (tail) ] keep-searching ] } | 
					
						
							| 
									
										
										
										
											2008-07-15 18:16:08 -04:00
										 |  |  |         } case
 | 
					
						
							| 
									
										
										
										
											2008-07-18 20:22:59 -04:00
										 |  |  |     ] if ; inline recursive
 | 
					
						
							| 
									
										
										
										
											2008-07-15 18:16:08 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | PRIVATE>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : search ( seq quot -- i elt )
 | 
					
						
							|  |  |  |     over empty? [ 2drop f f ] [ swap <flat-slice> (search) ] if ;
 | 
					
						
							|  |  |  |     inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : natural-search ( obj seq -- i elt )
 | 
					
						
							|  |  |  |     [ <=> ] with search ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-24 04:59:37 -04:00
										 |  |  | HINTS: natural-search array ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-15 18:16:08 -04:00
										 |  |  | : sorted-index ( obj seq -- i )
 | 
					
						
							|  |  |  |     natural-search drop ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : sorted-member? ( obj seq -- ? )
 | 
					
						
							|  |  |  |     dupd natural-search nip = ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : sorted-memq? ( obj seq -- ? )
 | 
					
						
							|  |  |  |     dupd natural-search nip eq? ;
 |