fmt and lint

This commit is contained in:
Olivier Gagnon 2022-04-08 00:39:45 -04:00
parent d956e47246
commit 2b2af797a7
3 changed files with 53 additions and 56 deletions

@ -6,7 +6,6 @@ import { startWorkerScript } from "../NetscriptWorker";
import { Augmentation } from "../Augmentation/Augmentation"; import { Augmentation } from "../Augmentation/Augmentation";
import { Augmentations } from "../Augmentation/Augmentations"; import { Augmentations } from "../Augmentation/Augmentations";
import { augmentationExists, installAugmentations } from "../Augmentation/AugmentationHelpers"; import { augmentationExists, installAugmentations } from "../Augmentation/AugmentationHelpers";
import { prestigeAugmentation } from "../Prestige";
import { AugmentationNames } from "../Augmentation/data/AugmentationNames"; import { AugmentationNames } from "../Augmentation/data/AugmentationNames";
import { killWorkerScript } from "../Netscript/killWorkerScript"; import { killWorkerScript } from "../Netscript/killWorkerScript";
import { CONSTANTS } from "../Constants"; import { CONSTANTS } from "../Constants";

@ -801,7 +801,7 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [
desc: (data: number[][]): string => { desc: (data: number[][]): string => {
return [ return [
"You are located in the top-left corner of the following grid:\n\n", "You are located in the top-left corner of the following grid:\n\n",
`  [${data.map(line => "[" + line + "]").join(",\n   ")}]\n\n`, `  [${data.map((line) => "[" + line + "]").join(",\n   ")}]\n\n`,
"You are trying to find the shortest path to the bottom-right corner of the grid,", "You are trying to find the shortest path to the bottom-right corner of the grid,",
"but there are obstacles on the grid that you cannot move onto.", "but there are obstacles on the grid that you cannot move onto.",
"These obstacles are denoted by '1', while empty spaces are denoted by 0.\n\n", "These obstacles are denoted by '1', while empty spaces are denoted by 0.\n\n",
@ -831,20 +831,18 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [
const minPathLength = dstY + dstX; // Math.abs(dstY - srcY) + Math.abs(dstX - srcX) const minPathLength = dstY + dstX; // Math.abs(dstY - srcY) + Math.abs(dstX - srcX)
const grid: number[][] = new Array(height); const grid: number[][] = new Array(height);
for(let y = 0; y < height; y++) for (let y = 0; y < height; y++) grid[y] = new Array(width).fill(0);
grid[y] = new Array(width).fill(0);
for(let y = 0; y < height; y++) { for (let y = 0; y < height; y++) {
for(let x = 0; x < width; x++) { for (let x = 0; x < width; x++) {
if(y == 0 && x == 0) continue; // Don't block start if (y == 0 && x == 0) continue; // Don't block start
if(y == dstY && x == dstX) continue; // Don't block destination if (y == dstY && x == dstX) continue; // Don't block destination
// Generate more obstacles the farther a position is from start and destination. // Generate more obstacles the farther a position is from start and destination.
// Raw distance factor peaks at 50% at half-way mark. Rescale to 40% max. // Raw distance factor peaks at 50% at half-way mark. Rescale to 40% max.
// Obstacle chance range of [15%, 40%] produces ~78% solvable puzzles // Obstacle chance range of [15%, 40%] produces ~78% solvable puzzles
const distanceFactor = Math.min(y + x, dstY - y + dstX - x) / minPathLength * 0.8; const distanceFactor = (Math.min(y + x, dstY - y + dstX - x) / minPathLength) * 0.8;
if (Math.random() < Math.max(0.15, distanceFactor)) if (Math.random() < Math.max(0.15, distanceFactor)) grid[y][x] = 1;
grid[y][x] = 1;
} }
} }
@ -860,7 +858,7 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [
//const prev: [[number, number] | undefined][] = new Array(height); //const prev: [[number, number] | undefined][] = new Array(height);
const queue = new MinHeap<[number, number]>(); const queue = new MinHeap<[number, number]>();
for(let y = 0; y < height; y++) { for (let y = 0; y < height; y++) {
distance[y] = new Array(width).fill(Infinity) as [number]; distance[y] = new Array(width).fill(Infinity) as [number];
//prev[y] = new Array(width).fill(undefined) as [undefined]; //prev[y] = new Array(width).fill(undefined) as [undefined];
} }
@ -871,10 +869,10 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [
// List in-bounds and passable neighbors // List in-bounds and passable neighbors
function* neighbors(y: number, x: number): Generator<[number, number]> { function* neighbors(y: number, x: number): Generator<[number, number]> {
if(validPosition(y - 1, x)) yield [y - 1, x]; // Up if (validPosition(y - 1, x)) yield [y - 1, x]; // Up
if(validPosition(y + 1, x)) yield [y + 1, x]; // Down if (validPosition(y + 1, x)) yield [y + 1, x]; // Down
if(validPosition(y, x - 1)) yield [y, x - 1]; // Left if (validPosition(y, x - 1)) yield [y, x - 1]; // Left
if(validPosition(y, x + 1)) yield [y, x + 1]; // Right if (validPosition(y, x + 1)) yield [y, x + 1]; // Right
} }
// Prepare starting point // Prepare starting point
@ -882,15 +880,16 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [
queue.push([0, 0], 0); queue.push([0, 0], 0);
// Take next-nearest position and expand potential paths from there // Take next-nearest position and expand potential paths from there
while(queue.size > 0) { while (queue.size > 0) {
const [y, x] = queue.pop() as [number, number]; const [y, x] = queue.pop() as [number, number];
for(const [yN, xN] of neighbors(y, x)) { for (const [yN, xN] of neighbors(y, x)) {
const d = distance[y][x] + 1; const d = distance[y][x] + 1;
if(d < distance[yN][xN]) { if (d < distance[yN][xN]) {
if(distance[yN][xN] == Infinity) // Not reached previously if (distance[yN][xN] == Infinity)
// Not reached previously
queue.push([yN, xN], d); queue.push([yN, xN], d);
else // Found a shorter path // Found a shorter path
queue.changeWeight(([yQ, xQ]) => yQ == yN && xQ == xN, d); else queue.changeWeight(([yQ, xQ]) => yQ == yN && xQ == xN, d);
//prev[yN][xN] = [y, x]; //prev[yN][xN] = [y, x];
distance[yN][xN] = d; distance[yN][xN] = d;
} }
@ -898,27 +897,33 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [
} }
// No path at all? // No path at all?
if(distance[dstY][dstX] == Infinity) if (distance[dstY][dstX] == Infinity) return ans == "";
return ans == "";
// There is a solution, require that the answer path is as short as the shortest // There is a solution, require that the answer path is as short as the shortest
// path we found // path we found
if(ans.length > distance[dstY][dstX]) if (ans.length > distance[dstY][dstX]) return false;
return false;
// Further verify that the answer path is a valid path // Further verify that the answer path is a valid path
let ansX = 0; let ansX = 0;
let ansY = 0; let ansY = 0;
for(const direction of ans) { for (const direction of ans) {
switch(direction) { switch (direction) {
case "U": ansY -= 1; break; case "U":
case "D": ansY += 1; break; ansY -= 1;
case "L": ansX -= 1; break; break;
case "R": ansX += 1; break; case "D":
default: return false; // Invalid character ansY += 1;
break;
case "L":
ansX -= 1;
break;
case "R":
ansX += 1;
break;
default:
return false; // Invalid character
} }
if(!validPosition(ansY, ansX)) if (!validPosition(ansY, ansX)) return false;
return false;
} }
// Path was valid, finally verify that the answer path brought us to the end coordinates // Path was valid, finally verify that the answer path brought us to the end coordinates

@ -28,16 +28,14 @@ abstract class BinHeap<T> {
/** Get the value of the root-most element of the heap, without changing the heap. */ /** Get the value of the root-most element of the heap, without changing the heap. */
public peek(): T | undefined { public peek(): T | undefined {
if(this.data.length == 0) if (this.data.length == 0) return undefined;
return undefined;
return this.data[0][1]; return this.data[0][1];
} }
/** Remove the root-most element of the heap and return the removed element's value. */ /** Remove the root-most element of the heap and return the removed element's value. */
public pop(): T | undefined { public pop(): T | undefined {
if(this.data.length == 0) if (this.data.length == 0) return undefined;
return undefined;
const value = this.data[0][1]; const value = this.data[0][1];
@ -52,9 +50,8 @@ abstract class BinHeap<T> {
/** Change the weight of an element in the heap. */ /** Change the weight of an element in the heap. */
public changeWeight(predicate: (value: T) => boolean, weight: number): void { public changeWeight(predicate: (value: T) => boolean, weight: number): void {
// Find first element with matching value, if any // Find first element with matching value, if any
const i = this.data.findIndex(e => predicate(e[1])); const i = this.data.findIndex((e) => predicate(e[1]));
if(i == -1) if (i == -1) return;
return;
// Update that element's weight // Update that element's weight
this.data[i][0] = weight; this.data[i][0] = weight;
@ -62,22 +59,22 @@ abstract class BinHeap<T> {
// And re-heapify if needed // And re-heapify if needed
const p = Math.floor((i - 1) / 2); const p = Math.floor((i - 1) / 2);
if(!this.heapOrderABeforeB(this.data[p][0], this.data[i][0])) // Needs to shift root-wards? if (!this.heapOrderABeforeB(this.data[p][0], this.data[i][0]))
// Needs to shift root-wards?
this.heapifyUp(i); this.heapifyUp(i);
else // Try shifting deeper // Try shifting deeper
this.heapifyDown(i); else this.heapifyDown(i);
} }
/** Restore heap condition, starting at index i and traveling towards root. */ /** Restore heap condition, starting at index i and traveling towards root. */
protected heapifyUp(i: number): void { protected heapifyUp(i: number): void {
// Swap the new element up towards root until it reaches root position or // Swap the new element up towards root until it reaches root position or
// settles under under a suitable parent // settles under under a suitable parent
while(i > 0) { while (i > 0) {
const p = Math.floor((i - 1) / 2); const p = Math.floor((i - 1) / 2);
// Reached heap-ordered state already? // Reached heap-ordered state already?
if(this.heapOrderABeforeB(this.data[p][0], this.data[i][0])) if (this.heapOrderABeforeB(this.data[p][0], this.data[i][0])) break;
break;
// Swap // Swap
const tmp = this.data[p]; const tmp = this.data[p];
@ -93,20 +90,17 @@ abstract class BinHeap<T> {
protected heapifyDown(i: number): void { protected heapifyDown(i: number): void {
// Swap the shifted element down in the heap until it either reaches the // Swap the shifted element down in the heap until it either reaches the
// bottom layer or is in correct order relative to it's children // bottom layer or is in correct order relative to it's children
while(i < this.data.length) { while (i < this.data.length) {
const l = i * 2 + 1; const l = i * 2 + 1;
const r = i * 2 + 2; const r = i * 2 + 2;
let toSwap = i; let toSwap = i;
// Find which one of element i and it's children should be closest to root // Find which one of element i and it's children should be closest to root
if(l < this.data.length && this.heapOrderABeforeB(this.data[l][0], this.data[toSwap][0])) if (l < this.data.length && this.heapOrderABeforeB(this.data[l][0], this.data[toSwap][0])) toSwap = l;
toSwap = l; if (r < this.data.length && this.heapOrderABeforeB(this.data[r][0], this.data[toSwap][0])) toSwap = r;
if(r < this.data.length && this.heapOrderABeforeB(this.data[r][0], this.data[toSwap][0]))
toSwap = r;
// Already in order? // Already in order?
if(i == toSwap) if (i == toSwap) break;
break;
// Not in order. Swap child that should be closest to root up to 'i' and repeat // Not in order. Swap child that should be closest to root up to 'i' and repeat
const tmp = this.data[toSwap]; const tmp = this.data[toSwap];
@ -124,7 +118,6 @@ abstract class BinHeap<T> {
protected abstract heapOrderABeforeB(weightA: number, weightB: number): boolean; protected abstract heapOrderABeforeB(weightA: number, weightB: number): boolean;
} }
/** Binary max-heap. */ /** Binary max-heap. */
export class MaxHeap<T> extends BinHeap<T> { export class MaxHeap<T> extends BinHeap<T> {
heapOrderABeforeB(weightA: number, weightB: number): boolean { heapOrderABeforeB(weightA: number, weightB: number): boolean {