Home Manual Reference Source

src/implementation/Deque.js

import {
	NotImplementedError,
	IndexError,
	ValueError,
} from '@failure-abstraction/error';

/**
 * Deque.
 */
export default function Deque() {}

/**
 * Deque.prototype.len.
 *
 * @return {Number}
 */
Deque.prototype.len = function () {
	throw new NotImplementedError('len');
};

/**
 * Deque.prototype.capacity.
 *
 * @return {Number}
 */
Deque.prototype.capacity = function () {
	throw new NotImplementedError('capacity');
};

/**
 * Deque.prototype.empty.
 *
 * @return {Boolean}
 */
Deque.prototype.empty = function () {
	return this.len() === 0;
};

/**
 * Deque.prototype[Symbol.iterator].
 *
 * @return {Iterable<any>}
 */
Deque.prototype[Symbol.iterator] = function () {
	return this.values();
};

/**
 * Deque.prototype.values.
 *
 * @return {Iterable<any>}
 */
Deque.prototype.values = function () {
	throw new NotImplementedError('values');
};

/**
 * Deque.prototype.append.
 *
 * @param {any} _x
 */
Deque.prototype.append = function (_x) {
	throw new NotImplementedError('append');
};

/**
 * Deque.prototype.appendleft.
 *
 * @param {any} _x
 */
Deque.prototype.appendleft = function (_x) {
	throw new NotImplementedError('appendleft');
};

/**
 * Deque.prototype.clear.
 *
 * @return {Deque}
 */
Deque.prototype.clear = function () {
	throw new NotImplementedError('clear');
};

/**
 * Deque.prototype.copy.
 *
 * @return {Deque}
 */
Deque.prototype.copy = function () {
	throw new NotImplementedError('copy');
};

/**
 * Deque.prototype.count.
 *
 * @param {any} x
 * @return {Number}
 */
Deque.prototype.count = function (x) {
	let c = 0;

	for (const element of this) {
		if (element === x) {
			++c;
		}
	}

	return c;
};

/**
 * Deque.prototype.extend.
 *
 * @param {Iterable<any>} iterable
 */
Deque.prototype.extend = function (iterable) {
	for (const x of iterable) {
		this.append(x);
	}

	return this;
};

/**
 * Deque.prototype.extendleft.
 *
 * @param {Iterable<any>} iterable
 */
Deque.prototype.extendleft = function (iterable) {
	for (const x of iterable) {
		this.appendleft(x);
	}

	return this;
};

/**
 * Deque.prototype._checkbounds.
 *
 * @param {Number} i
 */
Deque.prototype._checkbounds = function (i) {
	if (i < 0 || i >= this.len()) {
		throw new IndexError(i);
	}
};

/**
 * Deque.prototype._where.
 *
 * @param {Number} _i
 * @return {Array}
 */
Deque.prototype._where = function (_i) {
	throw new NotImplementedError('_where');
};

/**
 * Deque.prototype.get.
 *
 * @param {Number} i
 * @return {any}
 */
Deque.prototype.get = function (i) {
	const [container, index] = this._where(i);

	return container[index];
};

/**
 * Deque.prototype.set.
 *
 * @param {Number} i
 * @param {any} value
 * @return {Deque}
 */
Deque.prototype.set = function (i, value) {
	const [container, index] = this._where(i);

	container[index] = value;

	return this;
};

/**
 * Deque.prototype._range
 *
 * @param {Number} start
 * @param {Number} stop
 * @return {Iterable<any>}
 */
Deque.prototype._range = function* (start, stop) {
	for (let i = start; i < stop; ++i) {
		yield [i, this.get(i)];
	}
};

/**
 * Deque.prototype.index.
 *
 * @param {any} x
 * @param {Number} start
 * @param {Number} stop
 */
Deque.prototype.index = function (x, start = 0, stop = this.len()) {
	for (const [i, element] of this._range(start, stop)) {
		if (element === x) {
			return i;
		}
	}

	throw new ValueError('not found');
};

/**
 * Deque.prototype.pop.
 *
 * @return {any}
 */
Deque.prototype.pop = function () {
	throw new NotImplementedError('pop');
};

/**
 * Deque.prototype.popleft.
 *
 * @return {any}
 */
Deque.prototype.popleft = function () {
	throw new NotImplementedError('popleft');
};

/**
 * Deque.prototype.insert.
 *
 * @param {Number} i
 * @param {any} x
 */
Deque.prototype.insert = function (i, x) {
	this._checkbounds(i);

	this.append(x);

	let j = this.len() - 1;

	for (; i < j; --j) {
		const a = this.get(j);
		this.set(j, this.get(j - 1));
		this.set(j - 1, a);
	}

	return this;
};

/**
 * Deque.prototype.delete.
 *
 * @param {Number} i
 */
Deque.prototype.delete = function (i) {
	this._checkbounds(i);

	const length = this.len() - 1;

	for (; i < length; ++i) {
		this.set(i, this.get(i + 1));
	}

	this.pop();

	return this;
};

/**
 * Deque.prototype.remove.
 *
 * @param {any} value
 */
Deque.prototype.remove = function (value) {
	const i = this.index(value);

	this.delete(i);

	return this;
};

/**
 * Deque.prototype.reverse.
 *
 * @return {Deque}
 */
Deque.prototype.reverse = function () {
	for (let i = 0, j = this.len(); i < --j; ++i) {
		const a = this.get(i);
		const b = this.get(j);
		this.set(i, b);
		this.set(j, a);
	}

	return this;
};

/**
 * Deque.prototype.rotate.
 *
 * @param {Number} n
 */
Deque.prototype.rotate = function (n) {
	if (n > 0) {
		while (n-- > 0) {
			this.appendleft(this.pop());
		}
	} else if (n < 0) {
		while (n++ < 0) {
			this.append(this.popleft());
		}
	}

	return this;
};