529 lines
19 KiB
JavaScript
529 lines
19 KiB
JavaScript
"use strict";
|
|
var __extends = (this && this.__extends) || (function () {
|
|
var extendStatics = function (d, b) {
|
|
extendStatics = Object.setPrototypeOf ||
|
|
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
return extendStatics(d, b);
|
|
};
|
|
return function (d, b) {
|
|
if (typeof b !== "function" && b !== null)
|
|
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
extendStatics(d, b);
|
|
function __() { this.constructor = d; }
|
|
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
};
|
|
})();
|
|
var __read = (this && this.__read) || function (o, n) {
|
|
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
if (!m) return o;
|
|
var i = m.call(o), r, ar = [], e;
|
|
try {
|
|
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
}
|
|
catch (error) { e = { error: error }; }
|
|
finally {
|
|
try {
|
|
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
}
|
|
finally { if (e) throw e.error; }
|
|
}
|
|
return ar;
|
|
};
|
|
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
if (ar || !(i in from)) {
|
|
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
ar[i] = from[i];
|
|
}
|
|
}
|
|
return to.concat(ar || Array.prototype.slice.call(from));
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.Deque = void 0;
|
|
var ArrayContainer_1 = require("../internal/container/linear/ArrayContainer");
|
|
var ArrayIterator_1 = require("../internal/iterator/ArrayIterator");
|
|
var ArrayReverseIterator_1 = require("../internal/iterator/ArrayReverseIterator");
|
|
var NativeArrayIterator_1 = require("../internal/iterator/disposable/NativeArrayIterator");
|
|
var Pair_1 = require("../utility/Pair");
|
|
var InvalidArgument_1 = require("../exception/InvalidArgument");
|
|
var global_1 = require("../iterator/global");
|
|
var ErrorGenerator_1 = require("../internal/exception/ErrorGenerator");
|
|
/**
|
|
* Double ended queue.
|
|
*
|
|
* @author Jeongho Nam - https://github.com/samchon
|
|
*/
|
|
var Deque = /** @class */ (function (_super) {
|
|
__extends(Deque, _super);
|
|
function Deque() {
|
|
var args = [];
|
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
args[_i] = arguments[_i];
|
|
}
|
|
var _this = _super.call(this) || this;
|
|
// CONSTRUCTORS BRANCH
|
|
if (args.length === 0) {
|
|
_this.clear();
|
|
}
|
|
if (args.length === 1 && args[0] instanceof Array) {
|
|
// INITIALIZER CONSTRUCTOR
|
|
var array = args[0];
|
|
var first = new NativeArrayIterator_1.NativeArrayIterator(array, 0);
|
|
var last = new NativeArrayIterator_1.NativeArrayIterator(array, array.length);
|
|
_this.assign(first, last);
|
|
}
|
|
else if (args.length === 1 && args[0] instanceof Deque) {
|
|
// COPY CONSTRUCTOR
|
|
var container = args[0];
|
|
_this.assign(container.begin(), container.end());
|
|
}
|
|
else if (args.length === 2) {
|
|
// ASSIGN CONSTRUCTOR
|
|
_this.assign(args[0], args[1]);
|
|
}
|
|
return _this;
|
|
}
|
|
Deque.prototype.assign = function (first, second) {
|
|
// CLEAR PREVIOUS CONTENTS
|
|
this.clear();
|
|
// INSERT ITEMS
|
|
this.insert(this.end(), first, second);
|
|
};
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
Deque.prototype.clear = function () {
|
|
// CLEAR CONTENTS
|
|
this.matrix_ = [[]];
|
|
// RE-INDEX
|
|
this.size_ = 0;
|
|
this.capacity_ = Deque.MIN_CAPACITY;
|
|
};
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
Deque.prototype.resize = function (n) {
|
|
n = Deque._Emend(n, "resize");
|
|
var expansion = n - this.size();
|
|
if (expansion > 0)
|
|
this.insert(this.end(), expansion, undefined);
|
|
else if (expansion < 0)
|
|
this.erase(this.end().advance(-expansion), this.end());
|
|
};
|
|
/**
|
|
* Reserve {@link capacity} enable to store *n* elements.
|
|
*
|
|
* @param n The capacity to reserve.
|
|
*/
|
|
Deque.prototype.reserve = function (n) {
|
|
this._Reserve(Deque._Emend(n, "reserve"));
|
|
};
|
|
Deque.prototype._Reserve = function (n) {
|
|
// NEW MEMBERS TO BE ASSSIGNED
|
|
var matrix = [[]];
|
|
var length = this._Compute_col_size(n);
|
|
//--------
|
|
// RE-FILL
|
|
//--------
|
|
for (var r = 0; r < this.matrix_.length; ++r) {
|
|
var row = this.matrix_[r];
|
|
for (var c = 0; c < row.length; ++c) {
|
|
var new_row = matrix[matrix.length - 1];
|
|
if (matrix.length < Deque.ROW_SIZE &&
|
|
new_row.length === length) {
|
|
new_row = [];
|
|
matrix.push(new_row);
|
|
}
|
|
new_row.push(row[c]);
|
|
}
|
|
}
|
|
// ASSIGN MEMBERS
|
|
this.matrix_ = matrix;
|
|
this.capacity_ = n;
|
|
};
|
|
/**
|
|
* Shrink {@link capacity} to actual {@link size}.
|
|
*/
|
|
Deque.prototype.shrink_to_fit = function () {
|
|
this._Reserve(this.size());
|
|
};
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
Deque.prototype.swap = function (obj) {
|
|
this._Swap(obj);
|
|
};
|
|
Deque.prototype._Swap = function (obj) {
|
|
var _a, _b, _c;
|
|
// SWAP CONTENTS
|
|
_a = __read([obj.matrix_, this.matrix_], 2), this.matrix_ = _a[0], obj.matrix_ = _a[1];
|
|
_b = __read([obj.size_, this.size_], 2), this.size_ = _b[0], obj.size_ = _b[1];
|
|
_c = __read([obj.capacity_, this.capacity_], 2), this.capacity_ = _c[0], obj.capacity_ = _c[1];
|
|
};
|
|
Deque._Emend = function (n, method) {
|
|
n = Math.floor(n);
|
|
if (n <= 0)
|
|
throw new InvalidArgument_1.InvalidArgument("Error on Deque.".concat(method, "(): n must be positive integer -> (n = ").concat(n, ")"));
|
|
return n;
|
|
};
|
|
/* =========================================================
|
|
ACCESSORS
|
|
- BASIC ELEMENTS
|
|
- INDEX ACCESSORS
|
|
============================================================
|
|
BASIC ELEMENTS
|
|
--------------------------------------------------------- */
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
Deque.prototype.size = function () {
|
|
return this.size_;
|
|
};
|
|
/**
|
|
* The capacity to store elements.
|
|
*
|
|
* @return The capacity.
|
|
*/
|
|
Deque.prototype.capacity = function () {
|
|
return this.capacity_;
|
|
};
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
Deque.prototype.nth = function (index) {
|
|
return new Deque.Iterator(this, index);
|
|
};
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
Deque.prototype[Symbol.iterator] = function () {
|
|
return new Deque.ForOfAdaptor(this.matrix_);
|
|
};
|
|
Deque.prototype.source = function () {
|
|
return this;
|
|
};
|
|
/* ---------------------------------------------------------
|
|
INDEX ACCESSORS
|
|
--------------------------------------------------------- */
|
|
Deque.prototype._At = function (index) {
|
|
var indexPair = this._Fetch_index(index);
|
|
return this.matrix_[indexPair.first][indexPair.second];
|
|
};
|
|
Deque.prototype._Set = function (index, val) {
|
|
var indexPair = this._Fetch_index(index);
|
|
this.matrix_[indexPair.first][indexPair.second] = val;
|
|
};
|
|
Deque.prototype._Fetch_index = function (index) {
|
|
// Fetch row and column's index.
|
|
var row;
|
|
for (row = 0; row < this.matrix_.length; row++) {
|
|
var array = this.matrix_[row];
|
|
if (index < array.length)
|
|
break;
|
|
index -= array.length;
|
|
}
|
|
if (row === this.matrix_.length)
|
|
row--;
|
|
return new Pair_1.Pair(row, index);
|
|
};
|
|
Deque.prototype._Compute_col_size = function (capacity) {
|
|
if (capacity === void 0) { capacity = this.capacity_; }
|
|
// Get column size; {@link capacity_ capacity} / {@link ROW_SIZE row}.
|
|
return Math.floor(capacity / Deque.ROW_SIZE);
|
|
};
|
|
/* =========================================================
|
|
ELEMENTS I/O
|
|
- PUSH & POP
|
|
- INSERT
|
|
- ERASE
|
|
============================================================
|
|
PUSH & POP
|
|
--------------------------------------------------------- */
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
Deque.prototype.push = function () {
|
|
var items = [];
|
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
items[_i] = arguments[_i];
|
|
}
|
|
if (items.length === 0)
|
|
return this.size();
|
|
// INSERT BY RANGE
|
|
var first = new NativeArrayIterator_1.NativeArrayIterator(items, 0);
|
|
var last = new NativeArrayIterator_1.NativeArrayIterator(items, items.length);
|
|
this._Insert_by_range(this.end(), first, last);
|
|
// RETURN SIZE
|
|
return this.size();
|
|
};
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
Deque.prototype.push_front = function (val) {
|
|
// ADD CAPACITY & ROW
|
|
this._Try_expand_capacity(this.size_ + 1);
|
|
this._Try_add_row_at_front();
|
|
// INSERT VALUE
|
|
this.matrix_[0].unshift(val);
|
|
++this.size_;
|
|
};
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
Deque.prototype.push_back = function (val) {
|
|
// ADD CAPACITY & ROW
|
|
this._Try_expand_capacity(this.size_ + 1);
|
|
this._Try_add_row_at_back();
|
|
// INSERT VALUE
|
|
this.matrix_[this.matrix_.length - 1].push(val);
|
|
++this.size_;
|
|
};
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
Deque.prototype.pop_front = function () {
|
|
if (this.empty() === true)
|
|
throw ErrorGenerator_1.ErrorGenerator.empty(this.constructor, "pop_front");
|
|
// EREASE FIRST ELEMENT
|
|
this.matrix_[0].shift();
|
|
if (this.matrix_[0].length === 0 && this.matrix_.length > 1)
|
|
this.matrix_.shift();
|
|
// SHRINK SIZE
|
|
this.size_--;
|
|
};
|
|
Deque.prototype._Pop_back = function () {
|
|
// ERASE LAST ELEMENT
|
|
var lastArray = this.matrix_[this.matrix_.length - 1];
|
|
lastArray.pop();
|
|
if (lastArray.length === 0 && this.matrix_.length > 1)
|
|
this.matrix_.pop();
|
|
// SHRINK SIZE
|
|
this.size_--;
|
|
};
|
|
/* ---------------------------------------------------------
|
|
INSERT
|
|
--------------------------------------------------------- */
|
|
Deque.prototype._Insert_by_range = function (pos, first, last) {
|
|
var size = this.size_ + (0, global_1.distance)(first, last);
|
|
if (size === this.size_)
|
|
// FIRST === LAST
|
|
return pos;
|
|
if (pos.equals(this.end()) === true) {
|
|
// EXPAND CAPACITY IF REQUIRED
|
|
this._Try_expand_capacity(size);
|
|
// INSERT TO END
|
|
this._Insert_to_end(first, last);
|
|
// CHANGE POS TO RETURN
|
|
pos = this.nth(this.size_);
|
|
}
|
|
else {
|
|
// INSERT ITEMS IN THE MIDDLE
|
|
if (size > this.capacity_) {
|
|
// A TEMPORARY DEQUE
|
|
var deque = new Deque();
|
|
deque._Reserve(Math.max(size, Math.floor(this.capacity_ * Deque.MAGNIFIER)));
|
|
// INSERT ITEM SEQUENTIALLY
|
|
deque._Insert_to_end(this.begin(), pos);
|
|
deque._Insert_to_end(first, last);
|
|
deque._Insert_to_end(pos, this.end());
|
|
// AND SWAP THIS WITH THE TEMP
|
|
this._Swap(deque);
|
|
}
|
|
else
|
|
this._Insert_to_middle(pos, first, last);
|
|
}
|
|
this.size_ = size;
|
|
return pos;
|
|
};
|
|
Deque.prototype._Insert_to_middle = function (pos, first, last) {
|
|
var _a, _b;
|
|
var col_size = this._Compute_col_size();
|
|
// POSITION OF MATRIX
|
|
var indexes = this._Fetch_index(pos.index());
|
|
var row = this.matrix_[indexes.first];
|
|
var col = indexes.second;
|
|
// MOVE BACK SIDE TO TEMPORARY ARRAY
|
|
var back_items = row.splice(col);
|
|
// INSERT ITEMS
|
|
for (; !first.equals(last); first = first.next()) {
|
|
if (row.length === col_size &&
|
|
this.matrix_.length < Deque.ROW_SIZE) {
|
|
row = new Array();
|
|
var spliced_array = this.matrix_.splice(++indexes.first);
|
|
this.matrix_.push(row);
|
|
(_a = this.matrix_).push.apply(_a, __spreadArray([], __read(spliced_array), false));
|
|
}
|
|
row.push(first.value);
|
|
}
|
|
// INSERT ITEMS IN THE BACK SIDE
|
|
for (var i = 0; i < back_items.length; ++i) {
|
|
if (row.length === col_size &&
|
|
this.matrix_.length < Deque.ROW_SIZE) {
|
|
row = new Array();
|
|
var spliced_array = this.matrix_.splice(++indexes.first);
|
|
this.matrix_.push(row);
|
|
(_b = this.matrix_).push.apply(_b, __spreadArray([], __read(spliced_array), false));
|
|
}
|
|
row.push(back_items[i]);
|
|
}
|
|
};
|
|
Deque.prototype._Insert_to_end = function (first, last) {
|
|
// INSERT ITEMS IN THE BACK
|
|
for (; !first.equals(last); first = first.next()) {
|
|
// ADD ROW IF REQUIRED
|
|
this._Try_add_row_at_back();
|
|
// INSERT VALUE
|
|
this.matrix_[this.matrix_.length - 1].push(first.value);
|
|
}
|
|
};
|
|
Deque.prototype._Try_expand_capacity = function (size) {
|
|
if (size <= this.capacity_)
|
|
return false;
|
|
// MAX (CAPACITY * 1.5, TARGET SIZE)
|
|
size = Math.max(size, Math.floor(this.capacity_ * Deque.MAGNIFIER));
|
|
this._Reserve(size);
|
|
return true;
|
|
};
|
|
Deque.prototype._Try_add_row_at_front = function () {
|
|
var _a;
|
|
var col_size = this._Compute_col_size();
|
|
if (this.matrix_[0].length >= col_size &&
|
|
this.matrix_.length < Deque.ROW_SIZE) {
|
|
this.matrix_ = (_a = [[]]).concat.apply(_a, __spreadArray([], __read(this.matrix_), false));
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
};
|
|
Deque.prototype._Try_add_row_at_back = function () {
|
|
var col_size = this._Compute_col_size();
|
|
if (this.matrix_[this.matrix_.length - 1].length >= col_size &&
|
|
this.matrix_.length < Deque.ROW_SIZE) {
|
|
this.matrix_.push([]);
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
};
|
|
/* ---------------------------------------------------------
|
|
ERASE
|
|
--------------------------------------------------------- */
|
|
Deque.prototype._Erase_by_range = function (first, last) {
|
|
if (first.index() >= this.size())
|
|
return first;
|
|
// INDEXING
|
|
var size;
|
|
if (last.index() >= this.size())
|
|
// LAST IS END()
|
|
size = this.size() - first.index();
|
|
// LAST IS NOT END()
|
|
else
|
|
size = last.index() - first.index();
|
|
this.size_ -= size;
|
|
// ERASING
|
|
var first_row = null;
|
|
var second_row = null;
|
|
var i = 0;
|
|
while (size !== 0) {
|
|
// FIND MATCHED ROW AND COLUMN
|
|
var indexes = this._Fetch_index(first.index());
|
|
var row = this.matrix_[indexes.first];
|
|
var col = indexes.second;
|
|
// EARSE FROM THE ROW
|
|
var my_delete_size = Math.min(size, row.length - col);
|
|
row.splice(col, my_delete_size);
|
|
// TO MERGE
|
|
if (row.length !== 0)
|
|
if (i === 0)
|
|
first_row = row;
|
|
else
|
|
second_row = row;
|
|
// ERASE THE ENTIRE ROW IF REQUIRED
|
|
if (row.length === 0 && this.matrix_.length > 1)
|
|
this.matrix_.splice(indexes.first, 1);
|
|
// TO THE NEXT STEP
|
|
size -= my_delete_size;
|
|
++i;
|
|
}
|
|
// MERGE FIRST AND SECOND ROW
|
|
if (first_row !== null &&
|
|
second_row !== null &&
|
|
first_row.length + second_row.length <= this._Compute_col_size()) {
|
|
first_row.push.apply(first_row, __spreadArray([], __read(second_row), false));
|
|
this.matrix_.splice(this.matrix_.indexOf(second_row), 1);
|
|
}
|
|
return first;
|
|
};
|
|
return Deque;
|
|
}(ArrayContainer_1.ArrayContainer));
|
|
exports.Deque = Deque;
|
|
/**
|
|
*
|
|
*/
|
|
(function (Deque) {
|
|
// BODY
|
|
Deque.Iterator = ArrayIterator_1.ArrayIterator;
|
|
Deque.ReverseIterator = ArrayReverseIterator_1.ArrayReverseIterator;
|
|
//----
|
|
// CONSTANTS
|
|
//----
|
|
/**
|
|
* Row size of the {@link Deque.matrix_ matrix} which contains elements.
|
|
*
|
|
* Note that the {@link ROW_SIZE} affects on time complexity of accessing and inserting element.
|
|
* Accessing element is {@link ROW_SIZE} times slower than ordinary {@link Vector} and inserting element
|
|
* in middle position is {@link ROW_SIZE} times faster than ordinary {@link Vector}.
|
|
*
|
|
* When the {@link ROW_SIZE} returns 8, time complexity of accessing element is O(8) and inserting
|
|
* element in middle position is O(N/8). ({@link Vector}'s time complexity of accessement is O(1)
|
|
* and inserting element is O(N)).
|
|
*/
|
|
Deque.ROW_SIZE = 8;
|
|
/**
|
|
* Minimum {@link Deque.capacity}.
|
|
*
|
|
* Although a {@link Deque} has few elements, even no element is belonged to, the {@link Deque}
|
|
* keeps the minimum {@link Deque.capacity} at least.
|
|
*/
|
|
Deque.MIN_CAPACITY = 36;
|
|
/**
|
|
* Expansion ratio.
|
|
*/
|
|
Deque.MAGNIFIER = 1.5;
|
|
/**
|
|
* @internal
|
|
*/
|
|
var ForOfAdaptor = /** @class */ (function () {
|
|
function ForOfAdaptor(matrix) {
|
|
this.matrix_ = matrix;
|
|
this.row_ = 0;
|
|
this.col_ = 0;
|
|
}
|
|
ForOfAdaptor.prototype.next = function () {
|
|
if (this.row_ === this.matrix_.length)
|
|
return {
|
|
done: true,
|
|
value: undefined,
|
|
};
|
|
else {
|
|
var val = this.matrix_[this.row_][this.col_];
|
|
if (++this.col_ === this.matrix_[this.row_].length) {
|
|
++this.row_;
|
|
this.col_ = 0;
|
|
}
|
|
return {
|
|
done: false,
|
|
value: val,
|
|
};
|
|
}
|
|
};
|
|
ForOfAdaptor.prototype[Symbol.iterator] = function () {
|
|
return this;
|
|
};
|
|
return ForOfAdaptor;
|
|
}());
|
|
Deque.ForOfAdaptor = ForOfAdaptor;
|
|
})(Deque = exports.Deque || (exports.Deque = {}));
|
|
exports.Deque = Deque;
|
|
//# sourceMappingURL=Deque.js.map
|