Skip to content

Commit

Permalink
CODINGCONTRACT: Move internals to a separate folder (#1932)
Browse files Browse the repository at this point in the history
  • Loading branch information
G4mingJon4s authored Feb 12, 2025
1 parent 5bc9068 commit b61e93b
Show file tree
Hide file tree
Showing 33 changed files with 2,102 additions and 1,928 deletions.
10 changes: 5 additions & 5 deletions src/CodingContracts.ts → src/CodingContract/Contract.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { FactionName, CodingContractName } from "@enums";
import { CodingContractTypes } from "./data/codingcontracttypes";
import { CodingContractTypes } from "./ContractTypes";

import { Generic_fromJSON, Generic_toJSON, IReviverValue, constructorsForReviver } from "./utils/JSONReviver";
import { CodingContractEvent } from "./ui/React/CodingContractModal";
import { ContractFilePath, resolveContractFilePath } from "./Paths/ContractFilePath";
import { assertObject } from "./utils/TypeAssertion";
import { Generic_fromJSON, Generic_toJSON, IReviverValue, constructorsForReviver } from "../utils/JSONReviver";
import { CodingContractEvent } from "../ui/React/CodingContractModal";
import { ContractFilePath, resolveContractFilePath } from "../Paths/ContractFilePath";
import { assertObject } from "../utils/TypeAssertion";

// Numeric enum
/** Enum representing the different types of rewards a Coding Contract can give */
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { CodingContract, CodingContractRewardType, ICodingContractReward } from "./CodingContracts";
import { CodingContractTypes } from "./data/codingcontracttypes";
import { currentNodeMults } from "./BitNode/BitNodeMultipliers";
import { Factions } from "./Faction/Factions";
import { CodingContract, CodingContractRewardType, ICodingContractReward } from "./Contract";
import { CodingContractTypes } from "./ContractTypes";
import { currentNodeMults } from "../BitNode/BitNodeMultipliers";
import { Factions } from "../Faction/Factions";
import { Player } from "@player";
import { CodingContractName } from "@enums";
import { GetServer, GetAllServers } from "./Server/AllServers";
import { SpecialServers } from "./Server/data/SpecialServers";
import { Server } from "./Server/Server";
import { BaseServer } from "./Server/BaseServer";

import { getRandomIntInclusive } from "./utils/helpers/getRandomIntInclusive";
import { ContractFilePath, resolveContractFilePath } from "./Paths/ContractFilePath";
import { clampNumber } from "./utils/helpers/clampNumber";
import { GetServer, GetAllServers } from "../Server/AllServers";
import { SpecialServers } from "../Server/data/SpecialServers";
import { Server } from "../Server/Server";
import { BaseServer } from "../Server/BaseServer";

import { getRandomIntInclusive } from "../utils/helpers/getRandomIntInclusive";
import { ContractFilePath, resolveContractFilePath } from "../Paths/ContractFilePath";
import { clampNumber } from "../utils/helpers/clampNumber";

export function tryGeneratingRandomContract(numberOfTries: number): void {
/**
Expand Down
134 changes: 134 additions & 0 deletions src/CodingContract/ContractTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import { CodingContractName } from "@enums";
import { CodingContractSignatures } from "@nsdefs";

import { algorithmicStockTrader } from "./contracts/AlgorithmicStockTrader";
import { arrayJumpingGame } from "./contracts/ArrayJumpingGame";
import { compression } from "./contracts/Compression";
import { encryption } from "./contracts/Encryption";
import { findAllValidMathExpressions } from "./contracts/FindAllValidMathExpressions";
import { findLargestPrimeFactor } from "./contracts/FindLargestPrimeFactor";
import { generateIPAddresses } from "./contracts/GenerateIPAddresses";
import { hammingCode } from "./contracts/HammingCode";
import { mergeOverlappingIntervals } from "./contracts/MergeOverlappingIntervals";
import { minimumPathSumInATriangle } from "./contracts/MinimumPathSumInATriangle";
import { proper2ColoringOfAGraph } from "./contracts/Proper2ColoringOfAGraph";
import { sanitizeParenthesesInExpression } from "./contracts/SanitizeParenthesesInExpression";
import { shortestPathInAGrid } from "./contracts/ShortestPathInAGrid";
import { spiralizeMatrix } from "./contracts/SpiralizeMatrix";
import { squareRoot } from "./contracts/SquareRoot";
import { subarrayWithMaximumSum } from "./contracts/SubarrayWithMaximumSum";
import { totalWaysToSum } from "./contracts/TotalWaysToSum";
import { uniquePathsInAGrid } from "./contracts/UniquePathsInAGrid";

// This is the base interface, but should not be used for
// typechecking individual entries. Use the two types below for that.
interface CodingContractType<Data, Answer, State = Data> {
/**
* Function that returns a string with the problem's description.
* Requires the 'data' of a Contract as input
*/
desc: (data: Data) => string;
/** Difficulty of the contract. Higher is harder. */
difficulty: number;
/** Function that generates a valid 'state' for a contract type */
generate: () => State;
/**
* Transforms the 'state' for a contract into its 'data'. The state is
* stored persistently as JSON, so it must be serializable. The data is what
* is given to the user and shown in the description. If this function is
* ommitted, it will be the identity function (i.e. State == Data).
* You can use this to make problems where the "solver" is not a function
* that can be copy-pasted to user code to solve the problem.
*/
getData?: (state: State) => Data;
/** How many tries you get. Defaults to 10. */
numTries?: number;
/** Function that checks whether the players answer is correct. */
solver: (state: State, answer: Answer) => boolean;
/** Function that converts string answers to the expected answer format. */
convertAnswer: (answer: string) => Answer | null;
/** Function that validates the format of the provided answer. */
validateAnswer: (answer: unknown) => answer is Answer;
}

// This simple alias uses State == Data, and omits getData since it won't be used in this case.
type CodingContractSimpleType<Data, Answer> = Omit<CodingContractType<Data, Answer, Data>, "getData">;

// This alias has unique State and Data, and requires getData.
type CodingContractComplexType<Data, Answer, State> = Omit<CodingContractType<Data, Answer, State>, "getData"> & {
getData: (state: State) => Data;
};

type CodingContractDefinitions<Signatures extends Record<string, [unknown, unknown] | [unknown, unknown, unknown]>> = {
[T in keyof Signatures]: Signatures[T] extends [unknown, unknown, unknown]
? CodingContractComplexType<Signatures[T][0], Signatures[T][1], Signatures[T][2]>
: CodingContractSimpleType<Signatures[T][0], Signatures[T][1]>;
};
export type CodingContractTypes = CodingContractDefinitions<CodingContractSignatures>;

/* Helper functions for Coding Contract implementations */
export function removeBracketsFromArrayString(str: string): string {
let strCpy: string = str;
if (strCpy.startsWith("[")) {
strCpy = strCpy.slice(1);
}
if (strCpy.endsWith("]")) {
strCpy = strCpy.slice(0, -1);
}

return strCpy;
}

export function removeQuotesFromString(str: string): string {
let strCpy: string = str;
if (strCpy.startsWith('"') || strCpy.startsWith("'")) {
strCpy = strCpy.slice(1);
}
if (strCpy.endsWith('"') || strCpy.endsWith("'")) {
strCpy = strCpy.slice(0, -1);
}

return strCpy;
}

export function convert2DArrayToString(arr: number[][]): string {
const components: string[] = [];
for (const e of arr) {
let s = String(e);
s = ["[", s, "]"].join("");
components.push(s);
}

return components.join(",").replace(/\s/g, "");
}

export const isCodingContractName = (v: unknown): v is CodingContractName =>
Object.values(CodingContractName).some((a) => a === v);

export const CodingContractDefinitions: CodingContractTypes = {
...algorithmicStockTrader,
...arrayJumpingGame,
...compression,
...encryption,
...findAllValidMathExpressions,
...findLargestPrimeFactor,
...generateIPAddresses,
...hammingCode,
...mergeOverlappingIntervals,
...minimumPathSumInATriangle,
...proper2ColoringOfAGraph,
...sanitizeParenthesesInExpression,
...shortestPathInAGrid,
...spiralizeMatrix,
...squareRoot,
...subarrayWithMaximumSum,
...totalWaysToSum,
...uniquePathsInAGrid,
};

// This untyped variant is easier to work with when the specific type is not known.
// The specific shape is already checked by the CodingContractDefinitions type, so it is safe to assert the type.
export const CodingContractTypes = CodingContractDefinitions as Record<
CodingContractName,
CodingContractType<unknown, unknown, unknown>
>;
30 changes: 30 additions & 0 deletions src/CodingContract/Enums.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
export enum CodingContractName {
FindLargestPrimeFactor = "Find Largest Prime Factor",
SubarrayWithMaximumSum = "Subarray with Maximum Sum",
TotalWaysToSum = "Total Ways to Sum",
TotalWaysToSumII = "Total Ways to Sum II",
SpiralizeMatrix = "Spiralize Matrix",
ArrayJumpingGame = "Array Jumping Game",
ArrayJumpingGameII = "Array Jumping Game II",
MergeOverlappingIntervals = "Merge Overlapping Intervals",
GenerateIPAddresses = "Generate IP Addresses",
AlgorithmicStockTraderI = "Algorithmic Stock Trader I",
AlgorithmicStockTraderII = "Algorithmic Stock Trader II",
AlgorithmicStockTraderIII = "Algorithmic Stock Trader III",
AlgorithmicStockTraderIV = "Algorithmic Stock Trader IV",
MinimumPathSumInATriangle = "Minimum Path Sum in a Triangle",
UniquePathsInAGridI = "Unique Paths in a Grid I",
UniquePathsInAGridII = "Unique Paths in a Grid II",
ShortestPathInAGrid = "Shortest Path in a Grid",
SanitizeParenthesesInExpression = "Sanitize Parentheses in Expression",
FindAllValidMathExpressions = "Find All Valid Math Expressions",
HammingCodesIntegerToEncodedBinary = "HammingCodes: Integer to Encoded Binary",
HammingCodesEncodedBinaryToInteger = "HammingCodes: Encoded Binary to Integer",
Proper2ColoringOfAGraph = "Proper 2-Coloring of a Graph",
CompressionIRLECompression = "Compression I: RLE Compression",
CompressionIILZDecompression = "Compression II: LZ Decompression",
CompressionIIILZCompression = "Compression III: LZ Compression",
EncryptionICaesarCipher = "Encryption I: Caesar Cipher",
EncryptionIIVigenereCipher = "Encryption II: Vigenère Cipher",
SquareRoot = "Square Root",
}
Loading

0 comments on commit b61e93b

Please sign in to comment.