UNPKG

data-structure-typed

Version:
906 lines (784 loc) 26.1 kB
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] }); });