54 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			Factor
		
	
	
			
		
		
	
	
			54 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			Factor
		
	
	
| ! Copyright (C) 2008, 2009 Slava Pestov.
 | |
| ! See http://factorcode.org/license.txt for BSD license.
 | |
| USING: kernel sequences sequences.private accessors math
 | |
| math.order combinators hints arrays ;
 | |
| 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
 | |
| 
 | |
| DEFER: (search)
 | |
| 
 | |
| : keep-searching ( seq quot -- slice )
 | |
|     [ dup midpoint@ ] dip call collapse-slice slice boa (search) ; inline
 | |
| 
 | |
| : (search) ( quot: ( elt -- <=> ) seq -- i elt )
 | |
|     dup length 1 <= [
 | |
|         finish
 | |
|     ] [
 | |
|         decide {
 | |
|             { +eq+ [ finish ] }
 | |
|             { +lt+ [ [ (head) ] keep-searching ] }
 | |
|             { +gt+ [ [ (tail) ] keep-searching ] }
 | |
|         } case
 | |
|     ] if ; inline recursive
 | |
| 
 | |
| 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 ;
 | |
| 
 | |
| HINTS: natural-search array ;
 | |
| 
 | |
| : 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? ;
 |