data-structure-typed
Version:
Standard data structure
906 lines (784 loc) • 26.1 kB
text/typescript
import { Deque } from '../../../../src';
// import { isDebugTest } from '../../../config';
// const isDebug = isDebugTest;
describe('Deque - Basic Operations', () => {
let deque: Deque<number>;
beforeEach(() => {
deque = new Deque<number>([1, 2]);
});
it('push should add elements to the end', () => {
expect(deque.length).toBe(2);
expect(deque.last).toBe(2);
});
it('pop should remove elements from the end', () => {
expect(deque.pop()).toBe(2);
expect(deque.length).toBe(1);
expect(deque.pop()).toBe(1);
expect(deque.isEmpty()).toBeTruthy();
});
it('unshift should add elements to the beginning', () => {
deque.clear();
deque.unshift(1);
deque.unshift(2);
expect(deque.length).toBe(2);
expect(deque.first).toBe(2);
});
it('shift should remove elements from the beginning', () => {
deque.clear();
deque.unshift(1);
deque.unshift(2);
expect(deque.shift()).toBe(2);
expect(deque.length).toBe(1);
expect(deque.shift()).toBe(1);
expect(deque.isEmpty()).toBeTruthy();
});
it('at should retrieve the correct element', () => {
expect(deque.at(0)).toBe(1);
expect(deque.at(1)).toBe(2);
});
it('setAt should set the correct element', () => {
deque.setAt(0, 3);
expect(deque.at(0)).toBe(3);
});
it('should at after shifting', () => {
deque.clear();
for (let i = 0; i < 100; i++) {
deque.push(i);
}
for (let i = 0; i < 10; i++) {
expect(deque.shift()).toBe(i);
}
for (let i = 0; i < 90; i++) {
expect(deque.at(i)).toBe(i + 10);
}
});
it('should at after popping', () => {
deque.clear();
for (let i = 0; i < 100; i++) {
deque.push(i);
}
for (let i = 0; i < 10; i++) {
expect(deque.pop()).toBe(99 - i);
}
for (let i = 0; i < 90; i++) {
expect(deque.at(i)).toBe(i);
}
});
it('should clone', function () {
const deque = new Deque<string>();
deque.push('1');
deque.push('6');
deque.push('2');
deque.push('0');
deque.push('5');
deque.push('9');
expect(deque.length).toBe(6);
deque.delete('2');
expect(deque.length).toBe(5);
expect([...deque]).toEqual(['1', '6', '0', '5', '9']);
const cloned = deque.clone();
expect([...cloned]).toEqual(['1', '6', '0', '5', '9']);
expect(deque.length).toBe(5);
deque.delete('5');
expect(deque.length).toBe(4);
expect([...deque]).toEqual(['1', '6', '0', '9']);
expect([...cloned]).toEqual(['1', '6', '0', '5', '9']);
expect(cloned.length).toBe(5);
cloned.push('8');
expect(cloned.length).toBe(6);
cloned.delete('6');
expect(cloned.length).toBe(5);
cloned.delete('6');
expect(cloned.length).toBe(5);
});
});
describe('Deque - Complex Operations', () => {
let deque: Deque<number>;
beforeEach(() => {
deque = new Deque<number>();
});
it('addAt should insert elements at the specified position', () => {
deque.addAt(0, 1);
deque.addAt(1, 3);
deque.addAt(1, 2);
expect(deque.toArray()).toEqual([1, 2, 3]);
});
it('cut should remove elements after the specified position', () => {
deque.push(1);
deque.push(2);
deque.push(3);
expect(deque.length).toBe(3);
deque.cut(1, true);
expect(deque.length).toBe(2);
expect(deque.toArray()).toEqual([1, 2]);
const dq1 = new Deque([1, 2, 3, 4, 5, 6, 7]);
expect(dq1.length).toBe(7);
expect([...dq1.cut(3, true)]).toEqual([1, 2, 3, 4]);
expect(dq1.length).toBe(4);
expect([...dq1]).toEqual([1, 2, 3, 4]);
const dqCut = dq1.cut(2);
expect(dqCut.toArray()).toEqual([1, 2, 3]);
const dqCutFromBeginning = dqCut.cut(0, true);
expect(dqCutFromBeginning.toArray()).toEqual([1]);
dqCutFromBeginning.cut(-1, true);
expect(dqCutFromBeginning.toArray()).toEqual([]);
const dqCutFromNegative = dqCutFromBeginning.cut(-1);
expect([...dqCutFromNegative]).toEqual([]);
});
it('cutRest should remove elements after the specified position', () => {
deque.push(1);
deque.push(2);
deque.push(3);
deque.cutRest(1, true);
expect(deque.toArray()).toEqual([2, 3]);
const dq = new Deque([1, 2, 3, 4, 5, 6, 7]);
expect([...dq.cutRest(3, true)]).toEqual([4, 5, 6, 7]);
expect([...dq]).toEqual([4, 5, 6, 7]);
const deque1 = new Deque<number>();
deque1.push(1);
deque1.push(2);
deque1.push(3);
expect(deque1.toArray()).toEqual([1, 2, 3]);
expect(deque1.cutRest(1).toArray()).toEqual([2, 3]);
const dq1 = new Deque([1, 2, 3, 4, 5, 6, 7]);
expect([...dq1.cutRest(3)]).toEqual([4, 5, 6, 7]);
expect([...dq1]).toEqual([1, 2, 3, 4, 5, 6, 7]);
const dq2 = dq1.cutRest(0, true);
expect(dq2.toArray()).toEqual([1, 2, 3, 4, 5, 6, 7]);
dq2.cutRest(-1, true);
expect(dq2.toArray()).toEqual([1, 2, 3, 4, 5, 6, 7]);
const dq3 = dq2.cutRest(-1);
expect([...dq3]).toEqual([1, 2, 3, 4, 5, 6, 7]);
});
it('deleteAt should remove the element at the specified position', () => {
deque.push(1);
deque.push(2);
deque.push(3);
deque.deleteAt(1);
expect(deque.toArray()).toEqual([1, 3]);
deque.deleteAt(1);
deque.deleteAt(0);
expect(deque.toArray()).toEqual([]);
});
it('delete should remove all instances of an element', () => {
deque.delete(2);
expect(deque.toArray()).toEqual([]);
deque.push(1);
deque.push(2);
deque.push(2);
deque.push(3);
deque.delete(2);
expect(deque.toArray()).toEqual([1, 3]);
});
it('reverse should reverse the order of elements', () => {
deque.push(1);
deque.push(2);
deque.push(3);
deque.reverse();
expect(deque.toArray()).toEqual([3, 2, 1]);
});
it('unique should remove duplicate elements', () => {
deque.push(1);
const noNeedUnique = deque.unique();
expect(noNeedUnique).toBe(deque);
deque.push(2);
deque.push(2);
deque.push(3);
const uniquer = deque.unique();
expect(uniquer).toBe(deque);
expect(deque.toArray()).toEqual([1, 2, 3]);
});
it('sort should sort elements according to a comparator', () => {
deque.push(3);
deque.push(1);
deque.push(2);
deque.sort((a, b) => a - b);
expect([...deque]).toEqual([1, 2, 3]);
});
it('shrinkToFit should reduce the memory footprint', () => {
deque.shrinkToFit();
expect(deque.length).toBe(0);
expect(deque.has(1)).toBe(false);
expect(deque.bucketFirst).toBe(0);
expect(deque.bucketLast).toBe(0);
expect(deque.firstInBucket).toBe(2048);
expect(deque.lastInBucket).toBe(2048);
expect(deque.bucketCount).toBe(1);
expect(deque.buckets[0][0]).toEqual(undefined);
expect(deque.buckets.length).toEqual(1);
deque.push(1);
deque.shrinkToFit();
deque = new Deque([1, 2, 3, 4, 5], { bucketSize: 2 });
expect(deque.length).toBe(5);
expect(deque.has(1)).toBe(true);
expect(deque.bucketFirst).toBe(0);
expect(deque.bucketLast).toBe(2);
expect(deque.firstInBucket).toBe(0);
expect(deque.lastInBucket).toBe(0);
expect(deque.bucketCount).toBe(3);
expect(deque.buckets[0][0]).toBe(1);
expect(deque.buckets[2][0]).toBe(5);
expect(deque.buckets.length).toBe(3);
deque.shrinkToFit();
expect(deque.buckets).toEqual([[1, 2], [3, 4], [5]]);
deque.push(6);
deque.push(7);
deque.shrinkToFit();
expect(deque.buckets).toEqual([
[1, 2],
[3, 4],
[5, 6],
[7, 2]
]);
});
});
describe('Deque - Utility Operations', () => {
let deque: Deque<number>;
beforeEach(() => {
deque = new Deque<number>();
});
it('find should return the first element that matches the condition', () => {
expect(deque.first).toBe(undefined);
deque.push(1);
deque.push(2);
deque.push(3);
const found = deque.find(element => element > 1);
expect(found).toBe(2);
});
it('indexOf should return the index of the first occurrence of an element', () => {
deque.push(1);
deque.push(2);
deque.push(3);
const index = deque.indexOf(2);
expect(index).toBe(1);
expect(deque.indexOf(4)).toBe(-1);
});
it('toArray should convert the deque to an array', () => {
deque.push(1);
deque.push(2);
deque.push(3);
expect(deque.toArray()).toEqual([1, 2, 3]);
});
it('filter should filter elements based on a predicate', () => {
deque.push(1);
deque.push(2);
deque.push(3);
const filtered = deque.filter(element => element > 1);
expect(filtered.toArray()).toEqual([2, 3]);
});
it('map should apply a function to all elements', () => {
deque.push(1);
deque.push(2);
deque.push(3);
const mapped = deque.map(element => element * 2);
expect(mapped.toArray()).toEqual([2, 4, 6]);
});
it('print should print the deque elements', () => {
// const consoleSpy = jest.spyOn(console, 'log');
// deque.push(1);
// deque.push(2);
// deque.print();
// expect(consoleSpy).toHaveBeenCalledWith([1, 2]);
});
it('should maxLen work well', () => {
const dequeMaxLen = new Deque([3, 4, 5, 6, 7], { maxLen: 3 });
expect(dequeMaxLen.length).toBe(3);
expect(dequeMaxLen.toArray()).toEqual([5, 6, 7]);
dequeMaxLen.unshift(4);
dequeMaxLen.unshift(3);
expect(dequeMaxLen.length).toBe(3);
expect(dequeMaxLen.toArray()).toEqual([3, 4, 5]);
const dequeNoMaxLen = new Deque([3, 4, 5, 6, 7]);
expect(dequeNoMaxLen.length).toBe(5);
expect(dequeNoMaxLen.toArray()).toEqual([3, 4, 5, 6, 7]);
dequeNoMaxLen.unshift(4);
dequeNoMaxLen.unshift(3);
expect(dequeNoMaxLen.length).toBe(7);
expect(dequeNoMaxLen.toArray()).toEqual([3, 4, 3, 4, 5, 6, 7]);
});
});
describe('Deque - Additional Operations', () => {
let deque: Deque<number>;
beforeEach(() => {
deque = new Deque<number>();
});
it('push should add an element to the end', () => {
deque.push(1);
deque.push(2);
expect(deque.last).toBe(2);
expect(deque.length).toBe(2);
});
it('pop should remove and return the last element', () => {
deque.push(1);
deque.push(2);
expect(deque.pop()).toBe(2);
expect(deque.length).toBe(1);
});
it('unshift should add an element to the beginning', () => {
deque.unshift(1);
deque.unshift(2);
expect(deque.first).toBe(2);
expect(deque.length).toBe(2);
});
it('shift should remove and return the first element', () => {
deque.shift();
deque.unshift(1);
deque.unshift(2);
expect(deque.shift()).toBe(2);
expect(deque.length).toBe(1);
});
it('clear should reset the deque', () => {
deque.unshift(1);
deque.clear();
expect(deque.length).toBe(0);
expect(deque.isEmpty()).toBeTruthy();
});
// it('begin should yield elements from the beginning', () => {
// deque.push(1);
// deque.push(2);
// const iterator = deque.begin();
// expect(iterator.next().value).toBe(1);
// expect(iterator.next().value).toBe(2);
// });
// it('reverseBegin should yield elements in reverse order', () => {
// deque.push(1);
// deque.push(2);
// const iterator = deque.reverseBegin();
// expect(iterator.next().value).toBe(2);
// expect(iterator.next().value).toBe(1);
// });
});
describe('Deque - push Method', () => {
let deque: Deque<number>;
const bucketSize = 10;
beforeEach(() => {
deque = new Deque<number>([], {
bucketSize
});
});
it('push should add an element when deque is empty', () => {
deque.push(1);
expect(deque.last).toBe(1);
expect(deque.length).toBe(1);
});
it('push should add an element when lastInBucket is not at max', () => {
for (let i = 0; i < bucketSize - 1; i++) {
deque.push(i);
}
deque.push(bucketSize);
expect(deque.last).toBe(bucketSize);
expect(deque.length).toBe(bucketSize);
});
it('push should add an element and move to next bucket when last bucket is full', () => {
for (let i = 0; i < bucketSize; i++) {
deque.push(i);
}
deque.push(bucketSize + 1);
expect(deque.last).toBe(bucketSize + 1);
expect(deque.length).toBe(bucketSize + 1);
});
it('push should add an element and reallocate when last bucket and lastInBucket are at max', () => {
for (let i = 0; i < 100; i++) {
deque.push(i);
}
deque.push(100);
expect(deque.last).toBe(100);
expect(deque.length).toBeGreaterThan(bucketSize);
});
});
describe('Deque - pop Method', () => {
let deque: Deque<number>;
const bucketSize = 10;
beforeEach(() => {
deque = new Deque<number>([], {
bucketSize
});
});
it('pop should remove and return the last element', () => {
deque.push(1);
deque.push(2);
expect(deque.pop()).toBe(2);
expect(deque.length).toBe(1);
});
it('pop should handle popping the only element', () => {
deque.push(1);
expect(deque.pop()).toBe(1);
expect(deque.isEmpty()).toBeTruthy();
});
it('pop should adjust bucketLast and lastInBucket correctly', () => {
for (let i = 0; i < 100; i++) {
deque.push(i);
}
for (let i = 0; i < 1001; i++) {
const lastElement = deque.last;
expect(deque.pop()).toBe(lastElement);
}
});
});
describe('Deque - unshift Method', () => {
let deque: Deque<number>;
const bucketSize = 10;
beforeEach(() => {
deque = new Deque<number>([], {
bucketSize
});
});
it('unshift should add an element to the beginning when deque is empty', () => {
deque.unshift(1);
expect(deque.first).toBe(1);
expect(deque.length).toBe(1);
});
it('unshift should add an element to the beginning and adjust firstInBucket', () => {
for (let i = 0; i < 100; i++) {
deque.unshift(i);
}
deque.unshift(0);
expect(deque.first).toBe(0);
});
it('unshift should add an element and reallocate when needed', () => {
for (let i = 0; i < 100; i++) {
deque.unshift(i);
}
deque.unshift(-1);
expect(deque.first).toBe(-1);
});
});
describe('Deque - shift Method', () => {
let deque: Deque<number>;
const bucketSize = 10;
beforeEach(() => {
deque = new Deque<number>([], {
bucketSize
});
});
it('shift should remove and return the first element', () => {
deque.push(1);
deque.push(2);
expect(deque.shift()).toBe(1);
expect(deque.length).toBe(1);
});
it('shift should handle shifting the only element', () => {
deque.push(1);
expect(deque.shift()).toBe(1);
expect(deque.isEmpty()).toBeTruthy();
});
it('shift should adjust bucketFirst and firstInBucket correctly', () => {
for (let i = 0; i < 100; i++) {
deque.push(i);
}
for (let i = 0; i < 100; i++) {
const firstElement = deque.first;
expect(deque.shift()).toBe(firstElement);
}
});
});
describe('Deque Additional Methods', () => {
// Slice method implementation and test
test('slice should return a new list with specified range', () => {
const list = new Deque([1, 2, 3, 4, 5]);
const slicedList = list.slice(1, 4);
expect(slicedList.toArray()).toEqual([2, 3, 4]);
expect(list.length).toBe(5); // Original list unchanged
});
// Splice method implementation
test('splice should modify list and return removed elements', () => {
const list = new Deque([1, 2, 3, 4, 5]);
const removedList = list.splice(2, 2, 6, 7);
expect(list.toArray()).toEqual([1, 2, 6, 7, 5]);
expect(removedList.toArray()).toEqual([3, 4]);
});
// Concat method test
test('concat should combine multiple lists', () => {
const list1 = new Deque([1, 2]);
const list2 = new Deque([3, 4]);
const list3 = new Deque([5, 6]);
const concatenatedList = list1.concat(list2, list3);
expect(concatenatedList.toArray()).toEqual([1, 2, 3, 4, 5, 6]);
});
// Sort method test
test('sort should order elements in ascending order', () => {
const list = new Deque([5, 2, 8, 1, 9]);
list.sort((a, b) => a - b);
expect(list.toArray()).toEqual([1, 2, 5, 8, 9]);
});
// Reverse method test
test('reverse should invert the list order', () => {
const list = new Deque([1, 2, 3, 4, 5]);
list.reverse();
expect(list.toArray()).toEqual([5, 4, 3, 2, 1]);
});
// Join method test
test('join should convert list to string with separator', () => {
const list = new Deque(['a', 'b', 'c']);
expect(list.join('-')).toBe('a-b-c');
expect(list.join()).toBe('a,b,c');
});
// IndexOf method test
test('indexOf should return first occurrence index', () => {
const list = new Deque([1, 2, 3, 2, 1]);
expect(list.indexOf(2)).toBe(1);
expect(list.indexOf(4)).toBe(-1);
});
// LastIndexOf method test
test('lastIndexOf should return last occurrence index', () => {
const list = new Deque([1, 2, 3, 2, 1]);
expect(list.lastIndexOf(2)).toBe(3);
expect(list.lastIndexOf(4)).toBe(-1);
});
// findIndex method test
test('findIndex should return first occurrence index', () => {
const list = new Deque([1, 2, 3, 2, 1]);
expect(list.findIndex(item => item === 2)).toBe(1);
expect(list.findIndex(item => item === 4)).toBe(-1);
});
// fill method test
test('fill should return fill all the list', () => {
let list = new Deque([1, 2, 3, 2, 1]);
expect([...list.fill(9)]).toEqual([9, 9, 9, 9, 9]);
list = new Deque([1, 2, 3, 2, 1]);
expect([...list.fill(9, 2, 3)]).toEqual([1, 2, 9, 2, 1]);
list = new Deque([1, 2, 3, 2, 1]);
expect([...list.fill(9, -3, -2)]).toEqual([1, 2, 9, 2, 1]);
list = new Deque([1, 2, 3, 2, 1]);
expect([...list.fill(9, -2, -3)]).toEqual([1, 2, 3, 2, 1]);
});
});
describe('Deque', () => {
it('should initialize with default iterable with length function', () => {
class IterableNumbers {
private readonly _elements: number[] = [];
constructor(elements: number[]) {
this._elements = elements;
}
*[Symbol.iterator]() {
for (let i = 0; i < this._elements.length; ++i) {
yield this._elements[i];
}
}
length() {
return this._elements.length;
}
}
const numbers = new IterableNumbers([1, 6, 7, 3, 2, 4, 5]);
const deque = new Deque(numbers, { bucketSize: 3 });
expect(deque.length).toBe(7);
expect(deque.bucketSize).toBe(3);
expect(deque.maxLen).toBe(-1);
});
it('should initialize with default iterable with size function', () => {
class IterableNumbersWithSize {
private readonly _elements: number[] = [];
constructor(elements: number[]) {
this._elements = elements;
}
*[Symbol.iterator]() {
for (let i = 0; i < this._elements.length; ++i) {
yield this._elements[i];
}
}
size() {
return this._elements.length;
}
}
const numbers = new IterableNumbersWithSize([1, 6, 7, 3, 2, 4, 5]);
const deque = new Deque(numbers, { bucketSize: 3 });
expect(deque.length).toBe(7);
expect(deque.bucketSize).toBe(3);
expect(deque.maxLen).toBe(-1);
});
it('should initialize via toElementFn', () => {
const objArr: Array<{
key: number;
}> = [{ key: 1 }, { key: 6 }, { key: 7 }, { key: 3 }, { key: 2 }, { key: 4 }, { key: 5 }];
const deque = new Deque<number>(objArr, { toElementFn: item => item.key });
expect(deque.length).toBe(7);
expect(deque.has(1)).toBe(true);
expect(deque.has(7)).toBe(true);
expect(deque.has(8)).toBe(false);
});
it('should bucket properties are correct', () => {
const objArr: Array<{
key: number;
}> = [{ key: 1 }, { key: 6 }, { key: 7 }, { key: 3 }, { key: 2 }, { key: 4 }, { key: 5 }];
const deque = new Deque<number>(objArr, { toElementFn: item => item.key, bucketSize: 3 });
expect(deque.length).toBe(7);
expect(deque.has(1)).toBe(true);
expect(deque.bucketFirst).toBe(0);
expect(deque.bucketLast).toBe(2);
expect(deque.firstInBucket).toBe(1);
expect(deque.lastInBucket).toBe(1); // TODO may be a problem
expect(deque.bucketCount).toBe(3);
expect(deque.buckets).toEqual([
[, 1, 6],
[7, 3, 2],
[4, 5]
]);
});
it('should pop work well when bucket boundary is reached', () => {
const deque = new Deque<number>([1, 6, 7, 3, 2, 4, 5], { bucketSize: 3 });
expect(deque.length).toBe(7);
expect(deque.has(1)).toBe(true);
expect(deque.bucketFirst).toBe(0);
expect(deque.bucketLast).toBe(2);
expect(deque.firstInBucket).toBe(1);
expect(deque.lastInBucket).toBe(1); // TODO may be a problem
expect(deque.bucketCount).toBe(3);
expect(deque.buckets).toEqual([
[, 1, 6],
[7, 3, 2],
[4, 5]
]);
for (let i = 0; i < 3; ++i) deque.pop();
expect(deque.length).toBe(4);
expect(deque.has(1)).toBe(true);
expect(deque.bucketFirst).toBe(0);
expect(deque.bucketLast).toBe(1);
expect(deque.firstInBucket).toBe(1);
expect(deque.lastInBucket).toBe(1);
expect(deque.bucketCount).toBe(3);
expect(deque.buckets).toEqual([
[, 1, 6],
[7, 3, 2],
[4, 5]
]); // TODO may be a problem
deque.pop();
expect(deque.length).toBe(3);
expect(deque.has(1)).toBe(true);
expect(deque.bucketFirst).toBe(0);
expect(deque.bucketLast).toBe(1);
expect(deque.firstInBucket).toBe(1);
expect(deque.lastInBucket).toBe(0);
expect(deque.bucketCount).toBe(3);
expect(deque.buckets).toEqual([
[, 1, 6],
[7, 3, 2],
[4, 5]
]); // TODO may be a problem
});
it('should shift work well when bucket boundary is reached and should shrinkToFit', () => {
const deque = new Deque<number>([1, 6, 7, 3, 2, 4, 5], { bucketSize: 3 });
expect(deque.length).toBe(7);
expect(deque.has(1)).toBe(true);
expect(deque.bucketFirst).toBe(0);
expect(deque.bucketLast).toBe(2);
expect(deque.firstInBucket).toBe(1);
expect(deque.lastInBucket).toBe(1); // TODO may be a problem
expect(deque.bucketCount).toBe(3);
expect(deque.buckets).toEqual([
[, 1, 6],
[7, 3, 2],
[4, 5]
]);
for (let i = 0; i < 3; ++i) deque.shift();
expect(deque.length).toBe(4);
expect(deque.has(1)).toBe(false);
expect(deque.bucketFirst).toBe(1);
expect(deque.bucketLast).toBe(2);
expect(deque.firstInBucket).toBe(1);
expect(deque.lastInBucket).toBe(1);
expect(deque.bucketCount).toBe(3);
expect(deque.buckets).toEqual([
[, 1, 6],
[7, 3, 2],
[4, 5]
]); // TODO may be a problem
deque.shift();
expect(deque.length).toBe(3);
expect(deque.has(1)).toBe(false);
expect(deque.bucketFirst).toBe(1);
expect(deque.bucketLast).toBe(2);
expect(deque.firstInBucket).toBe(2);
expect(deque.lastInBucket).toBe(1);
expect(deque.bucketCount).toBe(3);
expect(deque.buckets).toEqual([
[, 1, 6],
[7, 3, 2],
[4, 5]
]); // TODO may be a problem
deque.shrinkToFit();
expect(deque.length).toBe(3);
expect(deque.has(1)).toBe(false);
expect(deque.bucketFirst).toBe(0);
expect(deque.bucketLast).toBe(1);
expect(deque.firstInBucket).toBe(2);
expect(deque.lastInBucket).toBe(1);
expect(deque.bucketCount).toBe(3);
expect(deque.buckets).toEqual([
[7, 3, 2],
[4, 5]
]); // TODO may be a problem
});
});
describe('classic uses', () => {
it('@example prize roulette', () => {
class PrizeRoulette {
private deque: Deque<string>;
constructor(prizes: string[]) {
// Initialize the deque with prizes
this.deque = new Deque<string>(prizes);
}
// Rotate clockwise to the right (forward)
rotateClockwise(steps: number): void {
const n = this.deque.length;
if (n === 0) return;
for (let i = 0; i < steps; i++) {
const last = this.deque.pop(); // Remove the last element
this.deque.unshift(last!); // Add it to the front
}
}
// Rotate counterclockwise to the left (backward)
rotateCounterClockwise(steps: number): void {
const n = this.deque.length;
if (n === 0) return;
for (let i = 0; i < steps; i++) {
const first = this.deque.shift(); // Remove the first element
this.deque.push(first!); // Add it to the back
}
}
// Display the current prize at the head
display() {
return this.deque.first;
}
}
// Example usage
const prizes = ['Car', 'Bike', 'Laptop', 'Phone', 'Watch', 'Headphones']; // Initialize the prize list
const roulette = new PrizeRoulette(prizes);
// Display the initial state
expect(roulette.display()).toBe('Car'); // Car
// Rotate clockwise by 3 steps
roulette.rotateClockwise(3);
expect(roulette.display()).toBe('Phone'); // Phone
// Rotate counterclockwise by 2 steps
roulette.rotateCounterClockwise(2);
expect(roulette.display()).toBe('Headphones'); // Headphones
});
it('@example sliding window', () => {
// Maximum function of sliding window
function maxSlidingWindow(nums: number[], k: number): number[] {
const n = nums.length;
if (n * k === 0) return [];
const deq = new Deque<number>();
const result: number[] = [];
for (let i = 0; i < n; i++) {
// Delete indexes in the queue that are not within the window range
if (deq.length > 0 && deq.first! === i - k) {
deq.shift();
}
// Remove all indices less than the current value from the tail of the queue
while (deq.length > 0 && nums[deq.last!] < nums[i]) {
deq.pop();
}
// Add the current index to the end of the queue
deq.push(i);
// Add the maximum value of the window to the results
if (i >= k - 1) {
result.push(nums[deq.first!]);
}
}
return result;
}
const nums = [1, 3, -1, -3, 5, 3, 6, 7];
const k = 3;
expect(maxSlidingWindow(nums, k)).toEqual([3, 3, 5, 5, 6, 7]); // Output: [3, 3, 5, 5, 6, 7]
});
});