2
2
import test from 'ava' ;
3
3
import { SegmentTree } from './segment-tree' ;
4
4
5
+ const findSumLinear = array => array . reduce ( ( s , v ) => s + v , 0 ) ;
6
+ const findMaxLinear = array => {
7
+ let max = - Infinity ;
8
+ for ( let i = 0 ; i < array . length ; ++ i ) {
9
+ if ( max < array [ i ] ) {
10
+ max = array [ i ] ;
11
+ }
12
+ }
13
+ return max ;
14
+ } ;
15
+
5
16
test ( 'creates tree instance' , t => {
6
17
const input = [ 1 , 2 , 3 , 4 , - 1 , 2 , - 2 , - 3 , - 4 , 10 , - 10 ] ;
7
18
const tree = new SegmentTree ( input , Math . min ) ;
@@ -16,9 +27,103 @@ test('creates tree instance and has query function', t => {
16
27
t . truthy ( tree . query ) ;
17
28
} ) ;
18
29
30
+ test ( 'returns fallback value when input length is zero' , t => {
31
+ const input = [ ] ;
32
+ const tree = new SegmentTree ( input , ( a , b ) => a + b , 42 ) ;
33
+
34
+ t . is ( tree . query ( 0 , 0 ) , 42 ) ;
35
+ } ) ;
36
+
19
37
test ( 'returns query result when input length equal 1' , t => {
20
38
const input = [ 1 ] ;
21
- const tree = new SegmentTree ( input , Math . min , - Infinity ) ;
39
+ const tree = new SegmentTree ( input , Math . min ) ;
22
40
23
41
t . is ( tree . query ( 0 , 1 ) , 1 ) ;
24
42
} ) ;
43
+
44
+ test ( 'query without arguments returns overall sum' , t => {
45
+ const input = [ 1 , 2 , 3 , 4 , - 1 , 2 , - 2 , - 3 , - 4 , 10 , - 10 ] ;
46
+ const tree = new SegmentTree ( input , ( a , b ) => a + b ) ;
47
+
48
+ t . is ( tree . query ( ) , 2 ) ;
49
+ } ) ;
50
+
51
+ test ( 'works with indexes outside an input array 1' , t => {
52
+ const input = [ 1 , 2 , 3 , 4 , - 1 , 2 , - 2 , - 3 , - 4 , 10 , - 10 ] ;
53
+ const tree = new SegmentTree ( input , ( a , b ) => a + b ) ;
54
+
55
+ t . is ( tree . query ( 5 , 50 ) , - 7 ) ;
56
+ } ) ;
57
+
58
+ test ( 'works with indexes outside an input array 2' , t => {
59
+ const input = [ 1 , 2 , 3 , 4 , - 1 , 2 , - 2 , - 3 , - 4 , 10 , - 10 ] ;
60
+ const tree = new SegmentTree ( input , ( a , b ) => a + b ) ;
61
+
62
+ t . is ( tree . query ( - 55 , 5 ) , 11 ) ;
63
+ } ) ;
64
+
65
+ test ( 'works with indexes outside an input array 3' , t => {
66
+ const input = [ 1 , 2 , 3 , 4 , - 1 , 2 , - 2 , - 3 , - 4 , 10 , - 10 ] ;
67
+ const tree = new SegmentTree ( input , ( a , b ) => a + b ) ;
68
+
69
+ t . is ( tree . query ( - 5500 , 5000 ) , 2 ) ;
70
+ } ) ;
71
+
72
+ test ( 'works with indexes outside an input array 4' , t => {
73
+ const input = [ 1 , 2 , 3 , 4 , - 1 , 2 , - 2 , - 3 , - 4 , 10 , - 10 ] ;
74
+ const tree = new SegmentTree ( input , ( a , b ) => a + b , 42 ) ;
75
+
76
+ t . is ( tree . query ( 3400 , 5000 ) , 42 ) ;
77
+ } ) ;
78
+
79
+ test ( 'works with indexes outside an input array 5' , t => {
80
+ const input = [ 1 , 2 , 3 , 4 , - 1 , 2 , - 2 , - 3 , - 4 , 10 , - 10 ] ;
81
+ const tree = new SegmentTree ( input , ( a , b ) => a + b , 42 ) ;
82
+
83
+ t . is ( tree . query ( - 5400 , - 3000 ) , 42 ) ;
84
+ } ) ;
85
+
86
+ test ( 'works with swapped indexes' , t => {
87
+ const input = [ 1 , 2 , 3 , 4 , - 1 , 2 , - 2 , - 3 , - 4 , 10 , - 10 ] ;
88
+ const tree = new SegmentTree ( input , ( a , b ) => a + b ) ;
89
+
90
+ t . is ( tree . query ( 5 , 2 ) , 8 ) ;
91
+ } ) ;
92
+
93
+ test ( 'returns sum of large arrays' , t => {
94
+ const input = Array ( 1e7 )
95
+ . fill ( 0 )
96
+ . map ( ( _ , i ) => Math . floor ( ( Math . random ( ) - 0.5 ) * 1e3 ) ) ;
97
+
98
+ const minIndex = 1000 ;
99
+ const maxIndex = 1e6 ;
100
+
101
+ // O(n) sum
102
+ const linearSum = findSumLinear ( input . slice ( minIndex , maxIndex + 1 ) ) ;
103
+
104
+ const tree = new SegmentTree ( input , ( a , b ) => a + b ) ;
105
+
106
+ // O(logn) sum
107
+ const segmentTreeSum = tree . query ( minIndex , maxIndex ) ;
108
+
109
+ t . is ( segmentTreeSum , linearSum ) ;
110
+ } ) ;
111
+
112
+ test ( 'returns max of large arrays' , t => {
113
+ const input = Array ( 1e7 )
114
+ . fill ( 0 )
115
+ . map ( ( _ , i ) => Math . floor ( ( Math . random ( ) - 0.5 ) * 1e9 ) ) ;
116
+
117
+ const minIndex = 1e4 ;
118
+ const maxIndex = 1e7 - 1e2 ;
119
+
120
+ // O(n) max
121
+ const linearMax = findMaxLinear ( input . slice ( minIndex , maxIndex + 1 ) ) ;
122
+
123
+ const tree = new SegmentTree ( input , Math . max ) ;
124
+
125
+ // O(logn) max
126
+ const segmentTreeMax = tree . query ( minIndex , maxIndex ) ;
127
+
128
+ t . is ( segmentTreeMax , linearMax ) ;
129
+ } ) ;
0 commit comments