puzzlescript
Version:
Play PuzzleScript games in your terminal!
203 lines • 5.66 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SortedList = exports.SortedArray = void 0;
class SortedArray {
constructor(comparator) {
this.comparator = comparator;
this.ary = [];
}
[Symbol.iterator]() {
// We only need to sort when we are iterating
this.ary.sort(this.comparator);
return this.ary[Symbol.iterator]();
}
add(item) {
const index = this.indexOf(item);
if (index < 0) {
this.ary.push(item);
}
}
delete(theItem) {
const index = this.indexOf(theItem);
if (index >= 0) {
this.ary.splice(index, 1);
}
}
size() {
return this.ary.length;
}
// Unused
// public has(item: T) {
// return this.indexOf(item) >= 0
// }
// public isEmpty() {
// return this.ary.length === 0
// }
// public clear() {
// this.ary = []
// }
indexOf(theItem) {
return this.ary.indexOf(theItem);
}
}
exports.SortedArray = SortedArray;
class ListItem {
constructor(item, previous, next) {
this.item = item;
this.previous = previous;
this.next = next;
}
}
class IteratorResultDone {
constructor() {
this.done = true;
this.value = {}; // tslint:disable-line:no-object-literal-type-assertion
}
}
class ListIteratorResult {
constructor(value) {
this.done = false;
this.value = value;
}
}
class ListIterator {
constructor(listHead) {
this.listHead = listHead;
this.current = null;
}
next(value) {
if (this.listHead) {
this.current = this.listHead;
this.listHead = null;
}
else if (this.current) {
// increment right before we return the item, not earlier because folks could have add items in
this.current = this.current.next;
}
if (this.current) {
return new ListIteratorResult(this.current.item);
}
else {
return new IteratorResultDone();
}
}
}
class SortedList {
constructor(comparator) {
this.comparator = comparator;
this.head = null;
}
[Symbol.iterator]() {
return new ListIterator(this.head);
}
add(newItem) {
let prev = null;
let current = this.head;
while (current) {
// check if the current node is less than the new node
const cmp = current.item === newItem ? 0 : this.comparator(current.item, newItem);
if (cmp === 0) {
return false; // item already exists in our list
}
else if (cmp > 0) {
break; // add here
}
prev = current;
current = current.next;
}
// Cases:
// - add to middle of list (current and prev) add just before current
// - add to end of list (!current and prev)
// - add to beginning of list (current and !prev)
// - empty list (!current and !prev)
if (prev && current) {
// insert before the prev
const node = new ListItem(newItem, prev, current);
prev.next = node;
current.previous = node;
// this.head = node
}
else if (prev) {
// same as previous case except we don't repoint current.previous
const node = new ListItem(newItem, prev, current);
prev.next = node;
// current.previous = node
// this.head = node
}
else if (current) {
// insert before the prev
const node = new ListItem(newItem, prev, current);
// prev.next = node
current.previous = node;
this.head = node;
}
else {
const node = new ListItem(newItem, prev, current);
// prev.next = node
// current.previous = node
this.head = node;
}
return true; // added
}
delete(item) {
const node = this.findNode(item);
if (node) {
// detach
if (node.previous) {
node.previous.next = node.next;
}
else if (this.head === node) {
this.head = node.next;
}
else {
throw new Error(`BUG: Invariant violation`);
}
if (node.next) {
node.next.previous = node.previous;
}
return true;
}
else {
throw new Error(`BUG: Item was not in the list`);
// return false
}
}
// Unused
// public has(item: T) {
// return !!this.findNode(item)
// }
isEmpty() {
return !this.head;
}
size() {
let size = 0;
for (const _item of this) {
size++;
}
return size;
}
// Unused
// public clear() {
// this.head = null
// }
// Unused
// public first() {
// if (this.head) {
// return this.head.item
// } else {
// throw new Error(`BUG: List was empty so cannot get first cell`)
// }
// }
findNode(item) {
let current = this.head;
while (current) {
if (current.item === item || this.comparator(current.item, item) === 0) {
return current;
}
current = current.next;
}
return null;
}
}
exports.SortedList = SortedList;
//# sourceMappingURL=sortedList.js.map