@alexaegis/advent-of-code-lib
Version:
Advent of Code Library
221 lines (220 loc) • 4.61 kB
JavaScript
"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
class LinkedListNode {
constructor(value) {
this.value = value;
}
prev;
next;
toString() {
return String(this.value);
}
*forward() {
yield this;
let current = this.next;
while (current !== void 0) {
yield current;
current = current.next;
}
}
*backward() {
yield this;
let current = this.prev;
while (current !== void 0) {
yield current;
current = current.prev;
}
}
first() {
let result = this.prev;
while (result?.prev !== void 0) {
result = result.prev;
}
return result;
}
last() {
let result = this.next;
while (result?.next !== void 0) {
result = result.next;
}
return result;
}
}
class CircularLinkedListNode extends LinkedListNode {
constructor(value, prev, next) {
super(value);
this.value = value;
this.prev = prev ?? this;
this.prev.next = this;
this.next = next ?? this;
this.next.prev = this;
}
prev;
next;
*round() {
let current = this;
do {
yield current.value;
current = current.next;
} while (current !== this);
}
getInFront(times = 1) {
let current = this.next;
let i = 1;
while (i < times) {
i++;
current = current.next;
}
return current;
}
getInBack(times = 1) {
let current = this.prev;
let i = 1;
while (i < times) {
i++;
current = current.prev;
}
return current;
}
distance(to) {
let current = this.next;
let distance = 1;
while (current !== to) {
distance++;
current = current.next;
}
return distance;
}
eject() {
this.prev.next = this.next;
this.next.prev = this.prev;
this.prev = void 0;
this.next = void 0;
return this;
}
putInFront(node) {
const oldNext = this.next;
this.next = node;
node.prev = this;
node.next = oldNext;
oldNext.prev = node;
}
putBehind(node) {
const oldPrev = this.prev;
this.prev = node;
node.next = this;
node.prev = oldPrev;
oldPrev.next = node;
}
*forward(infinite = false) {
yield this;
let current = this.next;
while (current !== (infinite ? void 0 : this)) {
yield current;
current = current.next;
}
}
*backward(infinite = false) {
yield this;
let current = this.prev;
while (current !== (infinite ? void 0 : this)) {
yield current;
current = current.prev;
}
}
}
class CircularLinkedList {
head;
constructor(initialData) {
const mainLink = initialData[0];
this.head = new CircularLinkedListNode(mainLink);
let skipped = false;
for (const item of initialData) {
if (skipped) {
this.add(item);
} else {
skipped = true;
}
}
}
length() {
return [...this.singleIterationNodes()].length;
}
add(t) {
return new CircularLinkedListNode(t, this.head.prev, this.head);
}
find(t) {
let cursor = this.head;
while (cursor.value !== t) {
cursor = cursor.next;
}
return cursor;
}
/**
* Infinite iterator
*/
*[Symbol.iterator]() {
let current = this.head;
for (; ; ) {
yield current.value;
current = current.next;
}
}
*singleIteration() {
let current = this.head;
do {
yield current.value;
current = current.next;
} while (current !== this.head);
}
*singleIterationNodes() {
let current = this.head;
do {
yield current;
current = current.next;
} while (current !== this.head);
}
toString() {
return [...this.singleIteration()].join(",");
}
}
class LinkedList {
start;
end;
_length = 0;
constructor(...initialData) {
for (const item of initialData) {
this.add(item);
}
}
add(...ts) {
for (const t of ts) {
if (!this.start || !this.end) {
this.start = new LinkedListNode(t);
this.end = this.start;
} else {
const link = new LinkedListNode(t);
link.prev = this.end;
this.end.next = link;
this.end = link;
}
this._length++;
}
}
get length() {
return this._length;
}
*[Symbol.iterator]() {
let current = this.start;
while (current !== void 0 && current !== this.end) {
yield current.value;
current = current.next;
}
}
toString() {
return [...this].join(",");
}
}
exports.CircularLinkedList = CircularLinkedList;
exports.CircularLinkedListNode = CircularLinkedListNode;
exports.LinkedList = LinkedList;