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