Skip to content

Commit 9b88ef1

Browse files
committed
Update binarySearch test with desc
- Update styles - Add description and logs to test - Log steps and description of binary search process - Make variables more descriptive by renaming
1 parent ce208bf commit 9b88ef1

File tree

3 files changed

+117
-41
lines changed

3 files changed

+117
-41
lines changed

data-structures/sorting-algos/binarySearch.js

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,52 @@
11

22
// BINARY SEARCH (ITERATIVE)
3-
export const binarySearchIterative = (arr, target) => {
4-
let left = 0;
5-
let right = arr.length;
3+
export const binarySearchIterative = (arr, targetVal) => {
4+
console.log('searchable', arr, ',','targetVal', targetVal);
5+
let leftPointer = 0;
6+
let rightPointer = arr.length;
67

7-
while (right > left) {
8-
const indexToCheck = Math.floor((left + right) / 2);
9-
const checking = arr[indexToCheck];
8+
while (rightPointer > leftPointer) {
9+
const midIdx = Math.floor((leftPointer + rightPointer) / 2);
10+
const midVal = arr[midIdx];
11+
console.log('setting leftPointer', leftPointer, 'rightPointer', rightPointer, 'midIdx', midIdx, '(val', midVal, ')');
12+
console.log('searching arr', arr.slice(leftPointer,rightPointer), 'with midVal', midVal, 'for targetVal', targetVal);
1013

11-
if (checking === target) {
12-
return indexToCheck;
13-
} else if (checking < target) {
14-
left = indexToCheck + 1;
14+
if (midVal === targetVal) {
15+
console.log('midVal === targetVal', midVal === targetVal);
16+
return midIdx;
17+
} else if (midVal < targetVal) {
18+
console.log('midVal < targetVal .. moving leftPointer to', midIdx + 1);
19+
leftPointer = midIdx + 1;
1520
} else {
16-
right = indexToCheck;
21+
console.log('midVal > targetVal .. moving rightPointer to', midIdx);
22+
rightPointer = midIdx;
1723
}
1824
}
1925
return null;
2026
};
2127

2228
// BINARY SEARCH (RECURSIVE)
23-
export const binarySearchRecursive = (arr, target, left = 0, right = arr.length) => {
24-
const indexToCheck = Math.floor((left + right) / 2);
25-
const valueToCheck = arr[indexToCheck];
26-
// console.log('arr', arr, 'valueToCheck', valueToCheck, 'target', target);
29+
export const binarySearchRecursive = (arr, targetVal, leftPointer = 0, rightPointer = arr.length) => {
30+
console.log('searchable', arr, ',','targetVal', targetVal);
31+
const midIdx = Math.floor((leftPointer + rightPointer) / 2);
32+
const midVal = arr[midIdx];
33+
console.log('setting leftPointer', leftPointer, 'rightPointer', rightPointer, 'midIdx', midIdx, '(val', midVal, ')');
34+
console.log('searching arr', arr.slice(leftPointer,rightPointer), 'with midVal', midVal, 'for targetVal', targetVal);
2735
if (arr.length > 0) {
28-
if (valueToCheck === target) {
29-
// console.log('valueToCheck === target', valueToCheck === target, 'indexToCheck', indexToCheck, 'valueToCheck', valueToCheck);
30-
return indexToCheck;
31-
} else if (valueToCheck < target) {
32-
left = indexToCheck + 1;
33-
// console.log('calling binarySearchRecursive(rarr, target, left)');
34-
return binarySearchRecursive(arr, target, left, right);
35-
} else if (valueToCheck > target) {
36-
right = indexToCheck;
37-
// console.log('calling binarySearchRecursive(larr, target, left, right)');
38-
return binarySearchRecursive(arr, target, left, right);
36+
if (midVal === targetVal) {
37+
console.log('midVal === targetVal', midVal === targetVal);
38+
return midIdx;
39+
} else if (midVal < targetVal) {
40+
console.log('midVal < targetVal .. moving leftPointer to', midIdx + 1);
41+
leftPointer = midIdx + 1;
42+
console.log('calling binarySearchRecursive(rarr, targetVal, leftPointer)');
43+
return binarySearchRecursive(arr, targetVal, leftPointer, rightPointer);
44+
} else if (midVal > targetVal) {
45+
rightPointer = midIdx;
46+
console.log('midVal > targetVal .. moving rightPointer to', midIdx);
47+
rightPointer = midIdx;
48+
console.log('calling binarySearchRecursive(larr, targetVal, leftPointer, rightPointer)');
49+
return binarySearchRecursive(arr, targetVal, leftPointer, rightPointer);
3950
}
4051
}
4152
return null;

data-structures/sorting-algos/binarySearch.test.js

Lines changed: 68 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,46 @@ util.inspect.defaultOptions.depth = null; // show full objects
1313
import console from 'console';
1414
const jestConsole = console;
1515

16-
// beforeEach(() => {
17-
// global.console = console;
18-
// console.log(style.color(255,0,255),'▷',style.reset,style.color(39),expect.getState().currentTestName,style.reset);
19-
// // console.log(expect.getState());
20-
// });
16+
beforeEach(() => {
17+
global.console = console;
18+
console.log(style.color(255,0,255),'▷',style.reset,style.color(39),expect.getState().currentTestName,style.reset);
19+
// console.log(expect.getState());
20+
});
21+
22+
afterEach(() => {
23+
global.console = jestConsole;
24+
console.log(style.color(99), style.hr.double, style.reset);
25+
});
2126

22-
// afterEach(() => {
23-
// global.console = jestConsole;
24-
// console.log(style.color(99), style.hr.double, style.reset);
25-
// });
27+
// const logItDescription = (description, callback) => {
28+
// console.log(style.green, ' ☞ ', style.reset,description);
29+
// it(description, callback);
30+
// };
2631

2732
const logItDescription = (description, callback) => {
28-
console.log(style.green, ' ☞ ', style.reset,description);
29-
it(description, callback);
33+
it(description, async () => {
34+
// Array to store captured log messages for this specific test
35+
const capturedLogs = [];
36+
37+
// Spy on console.log and push messages to our array
38+
const logSpy = jest.spyOn(console, 'log').mockImplementation((...args) => {
39+
capturedLogs.push(args);
40+
});
41+
42+
// Capture console.log output during the test's execution
43+
try {
44+
await callback(); // Assuming the callback might be async
45+
} finally {
46+
// Restore the original console.log behavior
47+
logSpy.mockRestore();
48+
49+
// Print the custom description and then the captured logs
50+
// console.log(style.green, ' ☞ ', style.reset, description);
51+
capturedLogs.forEach(logArgs => {
52+
console.log(' ↳ ', ...logArgs);
53+
});
54+
}
55+
});
3056
};
3157

3258
const logCategory = (description, callback) => {
@@ -39,17 +65,44 @@ const logDescribe = (description, callback) => {
3965
describe(description, callback);
4066
};
4167

42-
logCategory(`${style.bold}binarySearch${style.reset}`, () => {
68+
describe(`${style.bold}binarySearch${style.reset}`, () => {
69+
console.log(`
70+
${style.h1('# Binary Search')}
71+
Find an element by comparing the element to the middle element of a sorted
72+
array and--if not found--splitting, discarding sub-arrays until it is.
73+
74+
${style.h2('## Time Complexity')}
75+
Ο(log N) Ω(1) Θ(log N)
76+
77+
> Because we are cutting the list in half at each interval,
78+
the time complexity is \`O(log N)\`.
79+
> A sorted list of \`64\` elements will take at most \`log2(64) = 6\` comparisons.
80+
> \`Ω(1)\` because the target may be the middle element of the array
81+
82+
${style.h2('## Notes')}
83+
- For binary search to know which half of the data to discard after each split,
84+
the data source must always be sorted.
85+
86+
${style.h2('## Steps')}
87+
1. Check the middle value of the dataset.
88+
- If this value matches our target we can return the index
89+
90+
2. If the middle value is less than our target
91+
- Start at step 1 using the right half of the list.
92+
93+
3. If the middle value is greater than our target
94+
- Start at step 1 using the left half of the list.
95+
`);
4396

4497
// BINARY SEARCH (ITERATIVE)
45-
logDescribe(`${style.underline}${style.italic}binarySearch (Iterative)\n${style.reset}`, () => {
98+
describe(`${style.underline}${style.italic}(Iterative)\n${style.reset}`, () => {
4699

47100
logItDescription('should find index of target AT END of a 4 element searchable', () => {
48101
const searchable = [2, 4, 6, 8];
49102
const targetVal = 8;
50103
const expectedIdx = searchable.indexOf(targetVal);
51104
const receivedIdx = binarySearchIterative(searchable, targetVal);
52-
// console.log('expectedIdx', expectedIdx, 'receivedIdx', receivedIdx);
105+
console.log('expectedIdx', expectedIdx, 'receivedIdx', receivedIdx);
53106
assert.equal(receivedIdx, expectedIdx);
54107
});
55108

@@ -137,7 +190,7 @@ logCategory(`${style.bold}binarySearch${style.reset}`, () => {
137190
});
138191

139192
// BINARY SEARCH (RECURSIVE)
140-
logDescribe(`${style.underline}${style.italic}binarySearch (Recursive)\n${style.reset}`, () => {
193+
describe(`${style.underline}${style.italic}binarySearch (Recursive)\n${style.reset}`, () => {
141194

142195
logItDescription('should find index of target AT END of a 4 element searchable', () => {
143196
const searchable = [2, 4, 6, 8];

styles.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,18 @@ const style = {
3434
whitebg: '\x1b[47m',
3535
primaryFont: '\x1b[10m',
3636
strike: '\x1b[9m',
37+
h1: (text) => {
38+
return `${style.bold}${style.red}${text}${style.reset}`;
39+
},
40+
h2: (text) => {
41+
return `${style.bold}${style.purple}${text}${style.reset}`;
42+
},
43+
h3: (text) => {
44+
return `${style.bold}${style.orange}${text}${style.reset}`;
45+
},
46+
h4: (text) => {
47+
return `${style.bold}${style.blue}${text}${style.reset}`;
48+
},
3749
chain: (...styles) => {
3850
let chainedStyles = '';
3951
for (const styleName of styles) {

0 commit comments

Comments
 (0)