Paste: ternary-search-trees

Author: mrjbq7
Mode: factor
Date: Fri, 10 Sep 2010 18:05:11
Plain Text |
USING: accessors accessors.maybe arrays assocs combinators fry
kernel make math math.order sequences strings ;

IN: ternary-search-trees

<PRIVATE

<<
TUPLE: tree-node ch value exists lt eq gt ;
tree-node define-maybe-accessors
>>

: <tree-node> ( -- node )
    tree-node new ;

: (search) ( node ch -- node/f )
    over ch>> [
        dupd >=< swapd {
            { +eq+ [ nip ] }
            { +lt+ [ lt>> dup [ swap (search) ] [ nip ] if ] }
            { +gt+ [ gt>> dup [ swap (search) ] [ nip ] if ] }
        } case [ eq>> ] [ f ] if*
    ] [ 2drop f ] if* ;

: search ( key node -- node/f )
    [ 2dup [ empty? not ] [ and ] bi* ] [
        [ unclip-slice ] dip swap (search)
    ] while nip ;

: (insert) ( node ch -- node' )
    over ch>> [
        dupd >=< swapd {
            { +eq+ [ nip ] }
            { +lt+ [ [ <tree-node> ] maybe-lt swap (insert) ] }
            { +gt+ [ [ <tree-node> ] maybe-gt swap (insert) ] }
        } case
    ] [ >>ch ] if* [ <tree-node> ] maybe-eq ;

: insert ( value key node -- )
    swap [ (insert) ] each swap >>value t >>exists drop ;

PRIVATE>

<<
TUPLE: ternary-search-tree root count ;
ternary-search-tree define-maybe-accessors
>>

: <ternary-search-tree> ( -- tree )
    f 0 ternary-search-tree boa ;

: >ternary-search-tree ( assoc -- tree )
    <ternary-search-tree> assoc-clone-like ;

M: ternary-search-tree at* ( key tree -- value ? )
    root>> search [ [ value>> ] [ exists>> ] bi ] [ f f ] if* ;

M: ternary-search-tree new-assoc ( capacity exemplar -- newassoc )
    2drop <ternary-search-tree> ;

M: ternary-search-tree clear-assoc ( tree -- )
    f >>root 0 >>count drop ;

M: ternary-search-tree delete-at ( key tree -- )
    [ root>> search dup [ exists>> ] [ f ] if* ] keep
    swap [
        [ 1 - ] change-count drop
        f >>value f >>exists drop
    ] [ 2drop ] if ;

M: ternary-search-tree assoc-size ( tree -- n )
    count>> ;

M: ternary-search-tree set-at ( value key tree -- )
    [ 1 + ] change-count [ <tree-node> ] maybe-root insert ;

: (>alist) ( key node/f -- )
    [
        dup exists>> [ over over value>> 2array , ] when
        [ dupd lt>> (>alist) ]
        [
            dupd
            [ ch>> [ 1string append ] when* ] [ eq>> ] bi
            (>alist)
        ]
        [ dupd gt>> (>alist) ] tri drop
    ] [ drop ] if* ;

M: ternary-search-tree >alist
    "" swap root>> [ (>alist) ] { } make ;

M: ternary-search-tree clone
    >alist >ternary-search-tree ;

M: ternary-search-tree assoc-like
    drop dup ternary-search-tree?
    [ >ternary-search-tree ] unless ;

INSTANCE: ternary-search-tree assoc

New Annotation

Summary:
Author:
Mode:
Body: