-
Notifications
You must be signed in to change notification settings - Fork 7
/
random.js
108 lines (84 loc) · 2.69 KB
/
random.js
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
class Random {
constructor() {}
static pickNumberInRange(startInclusive, endInclusive) {
Random.#validateRange(startInclusive, endInclusive);
startInclusive = Math.ceil(startInclusive);
return (
Math.floor(Math.random() * (endInclusive + 1 - startInclusive)) +
startInclusive
);
}
static #isNumber(value) {
return typeof value === "number";
}
static #validateRange(startInclusive, endInclusive) {
if (!Random.#isNumber(startInclusive) || !Random.#isNumber(endInclusive)) {
throw new Error("arguments must be numbers.");
}
if (startInclusive < Number.MIN_SAFE_INTEGER) {
throw new Error(
"startInclusive cannot be less than Number.MIN_SAFE_INTEGER"
);
}
if (endInclusive > Number.MAX_SAFE_INTEGER) {
throw new Error(
"endInclusive cannot be greater than Number.MAX_SAFE_INTEGER."
);
}
if (startInclusive > endInclusive) {
throw new Error(
`startInclusive ${startInclusive} cannot be greater than endInclusive ${endInclusive}.`
);
}
if (endInclusive - startInclusive >= Number.MAX_VALUE) {
throw new Error("the input range is too large.");
}
}
static pickNumberInList(array) {
Random.#validateEmptyArray(array);
return array[Random.pickNumberInRange(0, array.length - 1)];
}
static #validateEmptyArray(array) {
if (!Array.isArray(array)) {
throw new Error("the argument must be an array.");
}
if (!array.every((v) => Random.#isNumber(v))) {
throw new Error("array elements must be numbers.");
}
if (array.length === 0) {
throw new Error("argument array cannot be empty.");
}
}
static pickUniqueNumbersInRange(startInclusive, endInclusive, count) {
Random.#validateIntsRange(startInclusive, endInclusive, count);
const result = [];
for (let i = startInclusive; i <= endInclusive; i++) {
result.push(i);
}
return Random.shuffle(result).slice(0, count);
}
static #validateIntsRange(startInclusive, endInclusive, count) {
if (
!Random.#isNumber(startInclusive) ||
!Random.#isNumber(endInclusive) ||
!Random.#isNumber(count)
) {
throw new Error("arguments must be numbers.");
}
if (count < 0) {
throw new Error("count cannot be less than zero.");
}
if (endInclusive - startInclusive + 1 < count) {
throw new Error(
`count: ${count} cannot be greater than the input range (endInclusive - startInclusive): ${
endInclusive - startInclusive
}.`
);
}
}
static shuffle(array) {
Random.#validateEmptyArray(array);
return array.sort(() => Math.random() - 0.5);
}
}
export default Random;