Skip to content

Commit 7f356ff

Browse files
committed
More detailed testing of binary insert
1 parent 8390b4f commit 7f356ff

File tree

2 files changed

+161
-19
lines changed

2 files changed

+161
-19
lines changed

src/__tests__/merge-insertion.test.ts

Lines changed: 160 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -53,27 +53,169 @@ test('_binInsertIdx', async () => {
5353
// A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
5454
const a = ['B','D','F','H','J','L','N','P','R','T','V','X','Z']
5555

56-
expect( await _binInsertIdx([], 'A', comp) ).toStrictEqual(0)
57-
expect( await _binInsertIdx(['B'], 'A', comp) ).toStrictEqual(0)
58-
expect( await _binInsertIdx(['B'], 'C', comp) ).toStrictEqual(1)
59-
expect( await _binInsertIdx(['B','D'], 'A', comp) ).toStrictEqual(0)
60-
expect( await _binInsertIdx(['B','D'], 'C', comp) ).toStrictEqual(1)
61-
expect( await _binInsertIdx(['B','D'], 'E', comp) ).toStrictEqual(2)
62-
63-
expect( await _binInsertIdx(a.slice(0,5), 'A', comp) ).toStrictEqual(0)
64-
expect( await _binInsertIdx(a.slice(0,5), 'E', comp) ).toStrictEqual(2)
65-
expect( await _binInsertIdx(a.slice(0,5), 'I', comp) ).toStrictEqual(4)
66-
expect( await _binInsertIdx(a.slice(0,5), 'K', comp) ).toStrictEqual(5)
67-
expect( await _binInsertIdx(a.slice(0,5), 'M', comp) ).toStrictEqual(5)
6856
await expect( _binInsertIdx(a.slice(0,5), 'J', comp) ).rejects.toThrow('already in')
6957

70-
expect( await _binInsertIdx(a.slice(0,6), 'A', comp) ).toStrictEqual(0)
71-
expect( await _binInsertIdx(a.slice(0,6), 'G', comp) ).toStrictEqual(3)
72-
expect( await _binInsertIdx(a.slice(0,6), 'M', comp) ).toStrictEqual(6)
58+
expect( await _binInsertIdx([], 'A', testComp(comp,0)) ).toStrictEqual(0)
59+
expect( await _binInsertIdx(['B'], 'A', testComp(comp,1)) ).toStrictEqual(0)
60+
expect( await _binInsertIdx(['B'], 'C', testComp(comp,1)) ).toStrictEqual(1)
7361

74-
expect( await _binInsertIdx(a.slice(0,7), 'A', comp) ).toStrictEqual(0)
75-
expect( await _binInsertIdx(a.slice(0,7), 'G', comp) ).toStrictEqual(3)
76-
expect( await _binInsertIdx(a.slice(0,7), 'O', comp) ).toStrictEqual(7)
62+
/* while L ≤ R:
63+
* M = L + floor( (R - L) / 2 )
64+
* if T < A[M] then: R = M − 1
65+
* else: L = M + 1 */
66+
const log :[string,string][] = []
67+
68+
/* A into B D
69+
* L R M =>
70+
* 0 1 0 A < B
71+
* 0 -1 ins L=0 */
72+
expect( await _binInsertIdx(['B','D'], 'A', testComp(comp,1,log)) ).toStrictEqual(0)
73+
expect(log).toStrictEqual([['A','B']])
74+
75+
log.length = 0
76+
/* C into B D
77+
* L R M =>
78+
* 0 1 0 C > B
79+
* 1 1 1 C < D
80+
* 1 0 ins L=1 */
81+
expect( await _binInsertIdx(['B','D'], 'C', testComp(comp,2,log)) ).toStrictEqual(1)
82+
expect(log).toStrictEqual([['C','B'],['C','D']])
83+
84+
log.length = 0
85+
/* E into B D
86+
* L R M =>
87+
* 0 1 0 E > B
88+
* 1 1 1 E > D
89+
* 2 1 ins L=2 */
90+
expect( await _binInsertIdx(['B','D'], 'E', testComp(comp,2,log)) ).toStrictEqual(2)
91+
expect(log).toStrictEqual([['E','B'],['E','D']])
92+
93+
log.length = 0
94+
/* A into B D F H J
95+
* L R M =>
96+
* 0 4 2 A < F
97+
* 0 1 0 A < B
98+
* 0 -1 ins L=0 */
99+
expect( await _binInsertIdx(a.slice(0,5), 'A', testComp(comp,2,log)) ).toStrictEqual(0)
100+
expect(log).toStrictEqual([['A','F'],['A','B']])
101+
102+
log.length = 0
103+
/* C into B D F H J
104+
* L R M =>
105+
* 0 4 2 C < F
106+
* 0 1 0 C > B
107+
* 1 1 1 C < D
108+
* 1 0 ins L=1 */
109+
expect( await _binInsertIdx(a.slice(0,5), 'C', testComp(comp,3,log)) ).toStrictEqual(1)
110+
expect(log).toStrictEqual([['C','F'],['C','B'],['C','D']])
111+
112+
log.length = 0
113+
/* E into B D F H J
114+
* L R M =>
115+
* 0 4 2 E < F
116+
* 0 1 0 E > B
117+
* 1 1 1 E > D
118+
* 2 1 ins L=2 */
119+
expect( await _binInsertIdx(a.slice(0,5), 'E', testComp(comp,3,log)) ).toStrictEqual(2)
120+
expect(log).toStrictEqual([['E','F'],['E','B'],['E','D']])
121+
122+
log.length = 0
123+
/* G into B D F H J
124+
* L R M =>
125+
* 0 4 2 G > F
126+
* 3 4 3 G < H
127+
* 3 2 ins L=3 */
128+
expect( await _binInsertIdx(a.slice(0,5), 'G', testComp(comp,2,log)) ).toStrictEqual(3)
129+
expect(log).toStrictEqual([['G','F'],['G','H']])
130+
131+
log.length = 0
132+
/* I into B D F H J
133+
* L R M =>
134+
* 0 4 2 I > F
135+
* 3 4 3 I > H
136+
* 4 4 4 I < J
137+
* 4 3 ins L=4 */
138+
expect( await _binInsertIdx(a.slice(0,5), 'I', testComp(comp,3,log)) ).toStrictEqual(4)
139+
expect(log).toStrictEqual([['I','F'],['I','H'],['I','J']])
140+
141+
log.length = 0
142+
/* K into B D F H J
143+
* L R M =>
144+
* 0 4 2 K > F
145+
* 3 4 3 K > H
146+
* 4 4 4 K > J
147+
* 5 4 ins L=5 */
148+
expect( await _binInsertIdx(a.slice(0,5), 'K', testComp(comp,3,log)) ).toStrictEqual(5)
149+
expect(log).toStrictEqual([['K','F'],['K','H'],['K','J']])
150+
151+
log.length = 0
152+
/* M into B D F H J
153+
* L R M =>
154+
* 0 4 2 M > F
155+
* 3 4 3 M > H
156+
* 4 4 4 M > J
157+
* 5 4 ins L=5 */
158+
expect( await _binInsertIdx(a.slice(0,5), 'M', testComp(comp,3,log)) ).toStrictEqual(5)
159+
expect(log).toStrictEqual([['M','F'],['M','H'],['M','J']])
160+
161+
log.length = 0
162+
/* A into B D F H J L
163+
* L R M =>
164+
* 0 5 2 A < F
165+
* 0 1 0 A < B
166+
* 0 -1 ins L=0 */
167+
expect( await _binInsertIdx(a.slice(0,6), 'A', testComp(comp,2,log)) ).toStrictEqual(0)
168+
expect(log).toStrictEqual([['A','F'],['A','B']])
169+
170+
log.length = 0
171+
/* G into B D F H J L
172+
* L R M =>
173+
* 0 5 2 G > F
174+
* 3 5 4 G < J
175+
* 3 3 3 G < H
176+
* 3 2 ins L=3 */
177+
expect( await _binInsertIdx(a.slice(0,6), 'G', testComp(comp,3,log)) ).toStrictEqual(3)
178+
expect(log).toStrictEqual([['G','F'],['G','J'],['G','H']])
179+
180+
log.length = 0
181+
/* M into B D F H J L
182+
* L R M =>
183+
* 0 5 2 M > F
184+
* 3 5 4 M > J
185+
* 5 5 5 M > L
186+
* 6 5 ins L=6 */
187+
expect( await _binInsertIdx(a.slice(0,6), 'M', testComp(comp,3,log)) ).toStrictEqual(6)
188+
expect(log).toStrictEqual([['M','F'],['M','J'],['M','L']])
189+
190+
log.length = 0
191+
/* A into B D F H J L N
192+
* L R M =>
193+
* 0 6 3 A < H
194+
* 0 2 1 A < D
195+
* 0 0 0 A < B
196+
* 0 -1 ins L=0 */
197+
expect( await _binInsertIdx(a.slice(0,7), 'A', testComp(comp,3,log)) ).toStrictEqual(0)
198+
expect(log).toStrictEqual([['A','H'],['A','D'],['A','B']])
199+
200+
log.length = 0
201+
/* G into B D F H J L N
202+
* L R M =>
203+
* 0 6 3 G < H
204+
* 0 2 1 G > D
205+
* 2 2 2 G > F
206+
* 3 2 ins L=3 */
207+
expect( await _binInsertIdx(a.slice(0,7), 'G', testComp(comp,3,log)) ).toStrictEqual(3)
208+
expect(log).toStrictEqual([['G','H'],['G','D'],['G','F']])
209+
210+
log.length = 0
211+
/* O into B D F H J L N
212+
* L R M =>
213+
* 0 6 3 O > H
214+
* 4 6 5 O > L
215+
* 6 6 6 O > N
216+
* 7 6 ins L=7 */
217+
expect( await _binInsertIdx(a.slice(0,7), 'O', testComp(comp,3,log)) ).toStrictEqual(7)
218+
expect(log).toStrictEqual([['O','H'],['O','L'],['O','N']])
77219
})
78220

79221
function testComp<T extends Comparable>(comp :Comparator<T>, maxCalls :number, log :[T,T][]|undefined = undefined) :Comparator<T> {

src/merge-insertion.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ export async function _binInsertIdx<T extends Comparable>(array :ReadonlyArray<T
9494
/* istanbul ignore next */ if (DEBUG) console.debug('binary insert',item,'into',array)
9595
let l = 0, r = array.length-1
9696
while (l <= r) {
97-
const m = Math.floor((l+r)/2)
97+
const m = l + Math.floor((r-l)/2)
9898
const c = await comparator([item, array[m]!])
9999
/* istanbul ignore next */ if (DEBUG) console.debug('left',l,'mid',m,'right',r,'item',item,c?'<':'>','array[m]',array[m])
100100
if (c) r = m - 1

0 commit comments

Comments
 (0)