trees, add pop/slurp operations
parent
45500b9137
commit
8b136cdd6d
|
@ -174,8 +174,39 @@ HELP: first-key
|
||||||
|
|
||||||
{ first-key first-entry last-key last-entry } related-words
|
{ first-key first-entry last-key last-entry } related-words
|
||||||
|
|
||||||
|
HELP: pop-tree-left
|
||||||
|
{ $values
|
||||||
|
{ "tree" tree }
|
||||||
|
{ "pair/f" { $maybe pair } }
|
||||||
|
}
|
||||||
|
{ $description "Removes and returns a key-value mapping associated with the lowest key in this map, or " { $link f } " if the map is empty." } ;
|
||||||
|
|
||||||
|
HELP: pop-tree-right
|
||||||
|
{ $values
|
||||||
|
{ "tree" tree }
|
||||||
|
{ "pair/f" { $maybe pair } }
|
||||||
|
}
|
||||||
|
{ $description "Removes and returns a key-value mapping associated with the highest key in this map, or " { $link f } " if the map is empty." } ;
|
||||||
|
|
||||||
|
{ pop-tree-left pop-tree-right } related-words
|
||||||
|
|
||||||
|
HELP: slurp-tree-left
|
||||||
|
{ $values
|
||||||
|
{ "tree" tree } { "quot" { $quotation ( ... entry -- ... ) } }
|
||||||
|
}
|
||||||
|
{ $description "Removes entries from a tree from the left (lowest key) and processes them with the quotation until the tree is empty." } ;
|
||||||
|
|
||||||
|
HELP: slurp-tree-right
|
||||||
|
{ $values
|
||||||
|
{ "tree" tree } { "quot" { $quotation ( ... entry -- ... ) } }
|
||||||
|
}
|
||||||
|
{ $description "Removes entries from a tree from the right (highest key) and processes them with the quotation until the tree is empty." } ;
|
||||||
|
|
||||||
|
{ slurp-tree-left slurp-tree-right } related-words
|
||||||
|
|
||||||
ARTICLE: "trees" "Binary search trees"
|
ARTICLE: "trees" "Binary search trees"
|
||||||
"This is a library for unbalanced binary search " { $link tree } "s. It is not intended to be used directly in most situations but rather as a base class for new trees, because performance can degrade to linear time storage/retrieval by the number of keys. These binary search trees conform to the assoc protocol."
|
"The " { $vocab-link "trees" } " vocabulary is a library for unbalanced binary search trees. A " { $link tree } " is not intended to be used directly in most situations but rather as a base class for new trees, because performance can degrade to linear time storage/retrieval by the number of keys. These binary search trees conform to the assoc protocol."
|
||||||
|
$nl
|
||||||
"Constructing trees:"
|
"Constructing trees:"
|
||||||
{ $subsections
|
{ $subsections
|
||||||
<tree>
|
<tree>
|
||||||
|
@ -198,6 +229,11 @@ ARTICLE: "trees" "Binary search trees"
|
||||||
lower-key lower-entry higher-key higher-entry
|
lower-key lower-entry higher-key higher-entry
|
||||||
floor-key floor-entry ceiling-key ceiling-entry
|
floor-key floor-entry ceiling-key ceiling-entry
|
||||||
}
|
}
|
||||||
|
"Pop/Slurp operations on trees:"
|
||||||
|
{ $subsections
|
||||||
|
pop-tree-left pop-tree-right
|
||||||
|
slurp-tree-left slurp-tree-right
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
ABOUT: "trees"
|
ABOUT: "trees"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
USING: accessors arrays assocs combinators kernel math
|
USING: accessors arrays assocs combinators fry kernel locals
|
||||||
math.combinatorics math.ranges namespaces random sequences
|
math math.combinatorics math.ranges namespaces random sequences
|
||||||
sequences.product tools.test trees trees.private ;
|
sequences.product tools.test trees trees.private ;
|
||||||
IN: trees.tests
|
IN: trees.tests
|
||||||
|
|
||||||
|
@ -191,3 +191,72 @@ CONSTANT: test-tree2 TREE{
|
||||||
[ 106 test-tree2 tailtree>alist[] keys ] unit-test
|
[ 106 test-tree2 tailtree>alist[] keys ] unit-test
|
||||||
{ { 108 110 112 114 116 118 120 } }
|
{ { 108 110 112 114 116 118 120 } }
|
||||||
[ 106 test-tree2 tailtree>alist(] keys ] unit-test
|
[ 106 test-tree2 tailtree>alist(] keys ] unit-test
|
||||||
|
|
||||||
|
|
||||||
|
{ { { 10 10 } TREE{ { 20 20 } { 30 30 } } } } [
|
||||||
|
TREE{ { 20 20 } { 10 10 } { 30 30 } } clone [
|
||||||
|
pop-tree-left
|
||||||
|
] keep 2array
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
{ { { 30 30 } TREE{ { 20 20 } { 10 10 } } } } [
|
||||||
|
TREE{ { 20 20 } { 10 10 } { 30 30 } } clone [
|
||||||
|
pop-tree-right
|
||||||
|
] keep 2array
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
{ { { 20 20 } TREE{ } } } [
|
||||||
|
TREE{ { 20 20 } } clone [
|
||||||
|
pop-tree-right
|
||||||
|
] keep 2array
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
{ { { 20 20 } TREE{ } } } [
|
||||||
|
TREE{ { 20 20 } } clone [
|
||||||
|
pop-tree-left
|
||||||
|
] keep 2array
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
{ f } [ TREE{ } pop-tree-left ] unit-test
|
||||||
|
{ f } [ TREE{ } pop-tree-right ] unit-test
|
||||||
|
|
||||||
|
: with-limited-calls ( n quot -- quot' )
|
||||||
|
[let
|
||||||
|
0 :> count!
|
||||||
|
'[ count _ >=
|
||||||
|
[ "too many calls" throw ]
|
||||||
|
[ count 1 + count! @ ] if
|
||||||
|
]
|
||||||
|
] ; inline
|
||||||
|
|
||||||
|
|
||||||
|
{ V{ { 10 10 } { 15 10 } { 20 20 }
|
||||||
|
{ 15 20 } { 30 30 } { 35 30 }
|
||||||
|
} } [
|
||||||
|
TREE{ { 20 20 } { 10 10 } { 30 30 } } clone V{ } clone [
|
||||||
|
dupd 6 [ [
|
||||||
|
over first {
|
||||||
|
{ [ dup 20 mod zero? ] [ drop [ first2 swap 5 - ] dip set-at ] }
|
||||||
|
{ [ dup 10 mod zero? ] [ drop [ first2 swap 5 + ] dip set-at ] }
|
||||||
|
[ 3drop ]
|
||||||
|
} cond
|
||||||
|
] [ push ] bi-curry* bi
|
||||||
|
] with-limited-calls 2curry slurp-tree-left
|
||||||
|
] keep
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
{ V{
|
||||||
|
{ 30 30 } { 25 30 } { 20 20 }
|
||||||
|
{ 25 20 } { 10 10 } { 5 10 } }
|
||||||
|
} [
|
||||||
|
TREE{ { 20 20 } { 10 10 } { 30 30 } } clone V{ } clone [
|
||||||
|
dupd 6 [ [
|
||||||
|
over first {
|
||||||
|
{ [ dup 20 mod zero? ] [ drop [ first2 swap 5 + ] dip set-at ] }
|
||||||
|
{ [ dup 10 mod zero? ] [ drop [ first2 swap 5 - ] dip set-at ] }
|
||||||
|
[ 3drop ]
|
||||||
|
} cond
|
||||||
|
] [ push ] bi-curry* bi
|
||||||
|
] with-limited-calls 2curry slurp-tree-right
|
||||||
|
] keep
|
||||||
|
] unit-test
|
||||||
|
|
|
@ -416,3 +416,37 @@ PRIVATE>
|
||||||
|
|
||||||
: height ( tree -- n )
|
: height ( tree -- n )
|
||||||
root>> node-height ;
|
root>> node-height ;
|
||||||
|
|
||||||
|
<PRIVATE
|
||||||
|
|
||||||
|
: (pop-tree-extremity) ( tree -- node/f )
|
||||||
|
dup root>> dup node-link
|
||||||
|
[ (prune-extremity) nip ]
|
||||||
|
[ [ delete-node swap root<< ] keep ] if* ;
|
||||||
|
|
||||||
|
: pop-tree-extremity ( tree -- node/f )
|
||||||
|
[ (pop-tree-extremity) ] [ over [ dec-count ] [ drop ] if ] bi
|
||||||
|
node>entry ;
|
||||||
|
|
||||||
|
: slurp-tree ( tree quot: ( ... entry -- ... ) -- ... )
|
||||||
|
[ drop [ count>> 0 = ] curry ]
|
||||||
|
[ [ [ pop-tree-extremity ] curry ] dip compose ] 2bi until ; inline
|
||||||
|
|
||||||
|
: pop-tree ( tree -- entry )
|
||||||
|
dup root>> dup [
|
||||||
|
drop pop-tree-extremity
|
||||||
|
] [ nip ] if ;
|
||||||
|
|
||||||
|
PRIVATE>
|
||||||
|
|
||||||
|
: pop-tree-left ( tree -- pair/f )
|
||||||
|
left [ pop-tree ] with-side ;
|
||||||
|
|
||||||
|
: pop-tree-right ( tree -- pair/f )
|
||||||
|
right [ pop-tree ] with-side ;
|
||||||
|
|
||||||
|
: slurp-tree-left ( tree quot: ( ... entry -- ... ) -- ... )
|
||||||
|
left [ slurp-tree ] with-side ; inline
|
||||||
|
|
||||||
|
: slurp-tree-right ( tree quot: ( ... entry -- ... ) -- ... )
|
||||||
|
right [ slurp-tree ] with-side ; inline
|
||||||
|
|
Loading…
Reference in New Issue