binary-search: faster and cleaner implementation using locals
parent
b7631c98cf
commit
8d3d425d44
|
@ -1,41 +1,29 @@
|
||||||
! Copyright (C) 2008, 2009 Slava Pestov.
|
! Copyright (C) 2008, 2010 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: kernel sequences sequences.private accessors math
|
USING: accessors arrays combinators hints kernel locals math
|
||||||
math.order combinators hints arrays ;
|
math.order sequences ;
|
||||||
IN: binary-search
|
IN: binary-search
|
||||||
|
|
||||||
<PRIVATE
|
<PRIVATE
|
||||||
|
|
||||||
: midpoint ( seq -- elt )
|
:: (search) ( seq from to quot: ( elt -- <=> ) -- i elt )
|
||||||
[ midpoint@ ] keep nth-unsafe ; inline
|
from to + 2/ :> midpoint@
|
||||||
|
midpoint@ seq nth :> midpoint
|
||||||
|
|
||||||
: decide ( quot seq -- quot seq <=> )
|
to from - 1 <= [
|
||||||
[ midpoint swap call ] 2keep rot ; inline
|
midpoint@ midpoint
|
||||||
|
|
||||||
: 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 {
|
midpoint quot call {
|
||||||
{ +eq+ [ finish ] }
|
{ +eq+ [ midpoint@ midpoint ] }
|
||||||
{ +lt+ [ [ (head) ] keep-searching ] }
|
{ +lt+ [ seq from midpoint@ quot (search) ] }
|
||||||
{ +gt+ [ [ (tail) ] keep-searching ] }
|
{ +gt+ [ seq midpoint@ to quot (search) ] }
|
||||||
} case
|
} case
|
||||||
] if ; inline recursive
|
] if ; inline recursive
|
||||||
|
|
||||||
PRIVATE>
|
PRIVATE>
|
||||||
|
|
||||||
: search ( seq quot -- i elt )
|
: search ( seq quot: ( elt -- <=> ) -- i elt )
|
||||||
over empty? [ 2drop f f ] [ swap <flat-slice> (search) ] if ;
|
over empty? [ 2drop f f ] [ [ 0 over length ] dip (search) ] if ;
|
||||||
inline
|
inline
|
||||||
|
|
||||||
: natural-search ( obj seq -- i elt )
|
: natural-search ( obj seq -- i elt )
|
||||||
|
|
Loading…
Reference in New Issue