function mergeSort(arr) {
if (arr.length <= 1) return arr;
const mid = Math.floor(arr.length / 2);
const left = mergeSort(arr.slice(0, mid));
const right = mergeSort(arr.slice(mid));
const result = [];
let i = 0, j = 0;
while (i < left.length && j < right.length) {
if (left[i] <= right[j]) result.push(left[i++]);
else result.push(right[j++]);
}
return result.concat(left.slice(i), right.slice(j));
}
function heapSort(arr) {
function heapify(size, i) {
let largest = i;
const left = 2 * i + 1, right = 2 * i + 2;
if (left < size && arr[left] > arr[largest]) largest = left;
if (right < size && arr[right] > arr[largest]) largest = right;
if (largest !== i) {
[arr[i], arr[largest]] = [arr[largest], arr[i]];
heapify(size, largest);
}
}
const n = arr.length;
for (let i = Math.floor(n / 2) - 1; i >= 0; i--) heapify(n, i);
for (let i = n - 1; i > 0; i--) {
[arr[0], arr[i]] = [arr[i], arr[0]];
heapify(i, 0);
}
return arr;
}
function insertionSort(arr) {
for (let i = 1; i < arr.length; i++) {
const key = arr[i];
let j = i - 1;
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
}
return arr;
}
function bubbleSort(arr) {
const n = arr.length;
for (let i = 0; i < n; i++) {
let swapped = false;
for (let j = 0; j < n - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
swapped = true;
}
}
if (!swapped) break;
}
return arr;
}
function radixSort(arr) {
if (arr.length === 0) return arr;
const maxVal = Math.max(...arr);
let exp = 1;
while (Math.floor(maxVal / exp) > 0) {
const output = new Array(arr.length);
const count = new Array(10).fill(0);
for (const val of arr) count[Math.floor(val / exp) % 10]++;
for (let i = 1; i < 10; i++) count[i] += count[i - 1];
for (let i = arr.length - 1; i >= 0; i--) {
const digit = Math.floor(arr[i] / exp) % 10;
output[--count[digit]] = arr[i];
}
arr.splice(0, arr.length, ...output);
exp *= 10;
}
return arr;
}
function padString(s, width, fill = ' ') {
return s.length >= width ? s : fill.repeat(width - s.length) + s;
}
function reverseString(s) {
return s.split('').reverse().join('');
}
function countWords(text) {
return text.trim().split(/\s+/).filter(w => w.length > 0).length;
}
function extractNumbers(text) {
const matches = text.match(/-?\d+\.?\d*/g);
return matches ? matches.map(Number) : [];
}
function validateUrl(url) {
const match = url.match(/^https?:\/\/([^/]+)/);
if (!match) return false;
return match[1].length > 0 && match[1].includes('.');
}
function validateIpAddress(addr) {
const v4parts = addr.split('.');
if (v4parts.length === 4) {
return v4parts.every(p => /^\d{1,3}$/.test(p) && parseInt(p) >= 0 && parseInt(p) <= 255);
}
const v6groups = addr.split(':');
return v6groups.length === 8 && v6groups.every(g => /^[0-9a-fA-F]{1,4}$/.test(g));
}
function validatePhone(phone) {
const digits = phone.replace(/\D/g, '');
return phone.startsWith('+') && digits.length >= 10 && digits.length <= 15;
}
function hashCrc32(data) {
let crc = 0xFFFFFFFF;
for (let i = 0; i < data.length; i++) {
crc ^= data.charCodeAt(i);
for (let j = 0; j < 8; j++) {
crc = (crc & 1) ? (crc >>> 1) ^ 0xEDB88320 : crc >>> 1;
}
}
return (crc ^ 0xFFFFFFFF) >>> 0;
}
class RateLimiter {
constructor(maxPerSecond) {
this.tokens = maxPerSecond;
this.maxTokens = maxPerSecond;
this.lastRefill = Date.now();
}
allow() {
this.refill();
if (this.tokens > 0) {
this.tokens--;
return true;
}
return false;
}
refill() {
const now = Date.now();
if (now - this.lastRefill >= 1000) {
this.tokens = this.maxTokens;
this.lastRefill = now;
}
}
}
class CircuitBreaker {
constructor(threshold, resetTimeoutMs = 30000) {
this.failureCount = 0;
this.threshold = threshold;
this.state = 'closed';
this.lastFailure = null;
this.resetTimeoutMs = resetTimeoutMs;
}
shouldAllow() {
if (this.state === 'closed') return true;
if (this.state === 'open' && this.lastFailure) {
if (Date.now() - this.lastFailure >= this.resetTimeoutMs) {
this.state = 'half_open';
return true;
}
return false;
}
return this.state === 'half_open';
}
recordFailure() {
this.failureCount++;
this.lastFailure = Date.now();
if (this.failureCount >= this.threshold) this.state = 'open';
}
recordSuccess() {
this.failureCount = 0;
this.state = 'closed';
}
}
function testMergeSort() {
const data = [5, 3, 8, 1, 2];
const result = mergeSort(data);
console.assert(JSON.stringify(result) === JSON.stringify([1, 2, 3, 5, 8]));
}
function testHeapSort() {
const data = [9, 4, 7, 1, 3];
const result = heapSort(data);
console.assert(JSON.stringify(result) === JSON.stringify([1, 3, 4, 7, 9]));
}
function testValidateEmail() {
console.assert(validateEmail("user@example.com"));
console.assert(!validateEmail("not-an-email"));
}
function testValidatePhone() {
console.assert(validatePhone("+1-555-0100"));
console.assert(!validatePhone("abc"));
}
function testCircuitBreaker() {
const cb = new CircuitBreaker(3, 30000);
console.assert(cb.shouldAllow());
}
function _mergeSorted(left, right) {
const result = [];
let i = 0, j = 0;
while (i < left.length && j < right.length) {
if (left[i] <= right[j]) {
result.push(left[i++]);
} else {
result.push(right[j++]);
}
}
return result.concat(left.slice(i), right.slice(j));
}
function _insertionSortSmall(arr) {
for (let i = 1; i < arr.length; i++) {
const key = arr[i];
let j = i;
while (j > 0 && arr[j - 1] > key) {
arr[j] = arr[j - 1];
j--;
}
arr[j] = key;
}
}