-
Notifications
You must be signed in to change notification settings - Fork 0
/
search.ts
149 lines (133 loc) · 3.81 KB
/
search.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
import fs from 'fs';
import { performance } from 'perf_hooks';
import numbers from './testdata/numbers.json';
enum Experiment {
FAST = 'fastFindDuplicates',
SLOWER = 'slowerFindDuplicates',
SLOWEST = 'slowestFindDuplicates',
}
const randomNumberInRange = (min: number, max: number): number =>
Math.floor(Math.random() * (max - min) + min);
const generateNumbersData = (size: number, uniques: number): Promise<void> =>
new Promise((resolve: () => void, reject: (err: Error) => void) => {
const nums: number[] = [...Array(size)].map((): number =>
randomNumberInRange(0, uniques)
);
fs.writeFile(
'./testdata/numbers.json',
JSON.stringify(nums),
(err: any) => {
if (err) {
reject(err);
} else {
resolve();
}
}
);
});
/**
* Go through an array of integers and return those that
* occur more than once. This has nested loops and will
* have a higher time complexity.
*
* example input: [1,2,3,1,4,5,6,7]
* returns output: [1]
*
* @param {number[]} nums - an array of random integers
* @return {number[]} - array of unique duplicates found
*/
const slowestFindDuplicates = (nums: number[]): number[] => {
const dupes: number[] = [];
for (let i = 0; i < nums.length; i++) {
for (let j = i + 1; j < nums.length; j++) {
if (nums[i] === nums[j] && dupes.indexOf(nums[i]) === -1) {
dupes.push(nums[i]);
}
}
}
return dupes;
};
/**
* Go through an array of integers and return those that
* occur more than once. This has no nested loops and
* will have a much lower time complexity.
*
* example input: [1,2,3,1,4,5,6,7]
* returns output: [1]
*
* @param {number[]} nums - an array of random integers
* @return {number[]} - array of unique duplicates found
*/
const slowerFindDuplicates = (nums: number[]): number[] => {
const sorted = nums.sort((a: number, b: number): number => (a > b ? 1 : -1));
const dupes: number[] = [];
for (let i = 0; i < sorted.length; i++) {
if (sorted[i] === sorted[i + 1] && dupes.indexOf(sorted[i]) === -1) {
dupes.push(sorted[i]);
}
}
return dupes;
};
/**
* Go through an array of integers and return those that
* occur more than once. This has less nested loops than
* the slowest example, but still has high time complexity.
* With that, it's still the shortest implementation.
*
* example input: [1,2,3,1,4,5,6,7]
* returns output: [1]
*
* @param {number[]} nums - an array of random integers
* @return {number[]} - array of unique duplicates found
*/
const fastFindDuplicates = (nums: number[]): number[] =>
nums
.filter((item: number, idx: number): boolean => nums.indexOf(item) === idx);
const measurePerformance = (
slice: number = 100,
experiment: Experiment
): number[] => {
const inputs: number[] = (numbers as number[]).slice(0, slice);
const start = performance.now();
let output: number[] = [];
switch (experiment) {
case Experiment.SLOWER: {
output = slowerFindDuplicates(inputs);
break;
}
case Experiment.FAST: {
output = fastFindDuplicates(inputs);
break;
}
case Experiment.SLOWEST: {
output = slowestFindDuplicates(inputs);
break;
}
}
console.info(
`=====> ${experiment} took ${Math.round(
performance.now() - start
)}ms with ${slice} items. <=====`
);
return output;
};
// generateNumbersData(1000000, 200);
console.info('Crunching numbers. Hang on.....');
console.log(
measurePerformance(
100000,
Experiment.FAST
).sort((a: number, b: number): number => (a > b ? 1 : -1))
);
console.log(
measurePerformance(
100000,
Experiment.SLOWER
).sort((a: number, b: number): number => (a > b ? 1 : -1))
);
console.log(
measurePerformance(
100000,
Experiment.SLOWEST
).sort((a: number, b: number): number => (a > b ? 1 : -1))
);