Skip to content

Instantly share code, notes, and snippets.

@OrangeDrangon
Last active March 31, 2024 20:08
Show Gist options
  • Save OrangeDrangon/8a08d2d7d425fddd2558e1c0c5fae78b to your computer and use it in GitHub Desktop.
Save OrangeDrangon/8a08d2d7d425fddd2558e1c0c5fae78b to your computer and use it in GitHub Desktop.
BitBurner Contract Solvers

All of the scripts for contracts in Bitburner.

import { getAllServers } from "getServers.js";
export function main(ns) {
const contracts = getAllServers(ns, "home").flatMap((server) => {
const onServer = ns.ls(server, ".cct").map((contract) => {
const type = ns.codingcontract.getContractType(contract, server);
const data = ns.codingcontract.getData(contract, server);
const didSolve = solve(type, data, server, contract, ns);
return `${server} - ${contract} - ${type} - ${didSolve || "FAILED!"}`;
});
return onServer;
});
ns.tprint(`Found ${contracts.length} contracts`);
contracts.forEach((contract) => void ns.tprint(contract));
}
function solve(type, data, server, contract, ns) {
let solution = "";
ns.tprint(type);
switch (type) {
case "Algorithmic Stock Trader I":
solution = maxProfit([1, data]);
break;
case "Algorithmic Stock Trader II":
solution = maxProfit([Math.ceil(data.length / 2), data]);
break;
case "Algorithmic Stock Trader III":
solution = maxProfit([2, data]);
break;
case "Algorithmic Stock Trader IV":
solution = maxProfit(data);
break;
case "Minimum Path Sum in a Triangle":
solution = solveTriangleSum(data, ns);
break;
case "Unique Paths in a Grid I":
solution = uniquePathsI(data);
break;
case "Unique Paths in a Grid II":
solution = uniquePathsII(data);
break;
case "Generate IP Addresses":
solution = generateIps(data);
break;
case "Find Largest Prime Factor":
solution = factor(data);
break;
case "Spiralize Matrix":
solution = spiral(data);
break;
case "Merge Overlapping Intervals":
solution = mergeOverlap(data);
break;
}
return (solution != "") ? ns.codingcontract.attempt(solution, contract, server, [true]) : "";
}
//ALGORITHMIC STOCK TRADER
function maxProfit(arrayData) {
let i, j, k;
let maxTrades = arrayData[0];
let stockPrices = arrayData[1];
// WHY?
let tempStr = "[0";
for (i = 0; i < stockPrices.length; i++) {
tempStr += ",0";
}
tempStr += "]";
let tempArr = "[" + tempStr;
for (i = 0; i < maxTrades - 1; i++) {
tempArr += "," + tempStr;
}
tempArr += "]";
let highestProfit = JSON.parse(tempArr);
for (i = 0; i < maxTrades; i++) {
for (j = 0; j < stockPrices.length; j++) { // Buy / Start
for (k = j; k < stockPrices.length; k++) { // Sell / End
if (i > 0 && j > 0 && k > 0) {
highestProfit[i][k] = Math.max(highestProfit[i][k], highestProfit[i - 1][k], highestProfit[i][k - 1], highestProfit[i - 1][j - 1] + stockPrices[k] - stockPrices[j]);
} else if (i > 0 && j > 0) {
highestProfit[i][k] = Math.max(highestProfit[i][k], highestProfit[i - 1][k], highestProfit[i - 1][j - 1] + stockPrices[k] - stockPrices[j]);
} else if (i > 0 && k > 0) {
highestProfit[i][k] = Math.max(highestProfit[i][k], highestProfit[i - 1][k], highestProfit[i][k - 1], stockPrices[k] - stockPrices[j]);
} else if (j > 0 && k > 0) {
highestProfit[i][k] = Math.max(highestProfit[i][k], highestProfit[i][k - 1], stockPrices[k] - stockPrices[j]);
} else {
highestProfit[i][k] = Math.max(highestProfit[i][k], stockPrices[k] - stockPrices[j]);
}
}
}
}
return highestProfit[maxTrades - 1][stockPrices.length - 1];
}
//SMALLEST TRIANGLE SUM
function solveTriangleSum(arrayData, ns) {
let triangle = arrayData;
let nextArray;
let previousArray = triangle[0];
for (let i = 1; i < triangle.length; i++) {
nextArray = [];
for (let j = 0; j < triangle[i].length; j++) {
if (j == 0) {
nextArray.push(previousArray[j] + triangle[i][j]);
} else if (j == triangle[i].length - 1) {
nextArray.push(previousArray[j - 1] + triangle[i][j]);
} else {
nextArray.push(Math.min(previousArray[j], previousArray[j - 1]) + triangle[i][j]);
}
}
previousArray = nextArray;
}
return Math.min.apply(null, nextArray);
}
//UNIQUE PATHS IN A GRID
function uniquePathsI(grid) {
const rightMoves = grid[0] - 1;
const downMoves = grid[1] - 1;
return Math.round(factorialDivision(rightMoves + downMoves, rightMoves) / (factorial(downMoves)));
}
function factorial(n) {
return factorialDivision(n, 1);
}
function factorialDivision(n, d) {
if (n == 0 || n == 1 || n == d)
return 1;
return factorialDivision(n - 1, d) * n;
}
function uniquePathsII(grid, ignoreFirst = false, ignoreLast = false) {
const rightMoves = grid[0].length - 1;
const downMoves = grid.length - 1;
let totalPossiblePaths = Math.round(factorialDivision(rightMoves + downMoves, rightMoves) / (factorial(downMoves)));
for (let i = 0; i < grid.length; i++) {
for (let j = 0; j < grid[i].length; j++) {
if (grid[i][j] == 1 && (!ignoreFirst || (i != 0 || j != 0)) && (!ignoreLast || (i != grid.length - 1 || j != grid[i].length - 1))) {
const newArray = [];
for (let k = i; k < grid.length; k++) {
newArray.push(grid[k].slice(j, grid[i].length));
}
let removedPaths = uniquePathsII(newArray, true, ignoreLast);
removedPaths *= uniquePathsI([i + 1, j + 1]);
totalPossiblePaths -= removedPaths;
}
}
}
return totalPossiblePaths;
}
//GENERATE IP ADDRESSES
function generateIps(num) {
num = num.toString();
const length = num.length;
const ips = [];
for (let i = 1; i < length - 2; i++) {
for (let j = i + 1; j < length - 1; j++) {
for (let k = j + 1; k < length; k++) {
const ip = [
num.slice(0, i),
num.slice(i, j),
num.slice(j, k),
num.slice(k, num.length)
];
let isValid = true;
ip.forEach(seg => {
isValid = isValid && isValidIpSegment(seg);
});
if (isValid) ips.push(ip.join("."));
}
}
}
return ips;
}
function isValidIpSegment(segment) {
if (segment[0] == "0" && segment != "0") return false;
segment = Number(segment);
if (segment < 0 || segment > 255) return false;
return true;
}
//GREATEST FACTOR
function factor(num) {
for (let div = 2; div <= Math.sqrt(num); div++) {
if (num % div != 0) {
continue;
}
num = num / div;
div = 2;
}
return num;
}
//SPIRALIZE Matrix
function spiral(arr, accum = []) {
if (arr.length === 0 || arr[0].length === 0) {
return accum;
}
accum = accum.concat(arr.shift());
if (arr.length === 0 || arr[0].length === 0) {
return accum;
}
accum = accum.concat(column(arr, arr[0].length - 1));
if (arr.length === 0 || arr[0].length === 0) {
return accum;
}
accum = accum.concat(arr.pop().reverse());
if (arr.length === 0 || arr[0].length === 0) {
return accum;
}
accum = accum.concat(column(arr, 0).reverse());
if (arr.length === 0 || arr[0].length === 0) {
return accum;
}
return spiral(arr, accum);
}
function column(arr, index) {
const res = [];
for (let i = 0; i < arr.length; i++) {
const elm = arr[i].splice(index, 1)[0];
if (elm) {
res.push(elm);
}
}
return res;
}
// Merge Overlapping Intervals
function mergeOverlap(intervals) {
intervals.sort(([minA], [minB]) => minA - minB);
for (let i = 0; i < intervals.length; i++) {
for (let j = i + 1; j < intervals.length; j++) {
const [min, max] = intervals[i];
const [laterMin, laterMax] = intervals[j];
if (laterMin <= max) {
const newMax = laterMax > max ? laterMax : max;
const newInterval = [min, newMax];
intervals[i] = newInterval;
intervals.splice(j, 1);
j = i;
}
}
}
return intervals;
}
// Generate IP Addresses
function generateIps(num) {
num = num.toString();
const length = num.length;
const ips = [];
for (let i = 1; i < length - 2; i++) {
for (let j = i + 1; j < length - 1; j++) {
for (let k = j + 1; k < length; k++) {
const ip = [
num.slice(0, i),
num.slice(i, j),
num.slice(j, k),
num.slice(k, num.length)
];
let isValid = true;
ip.forEach(seg => {
isValid = isValid && isValidIpSegment(seg);
});
if (isValid) ips.push(ip.join("."));
}
}
}
return ips;
}
function isValidIpSegment(segment) {
if (segment[0] == "0" && segment != "0") return false;
segment = Number(segment);
if (segment < 0 || segment > 255) return false;
return true;
}
// Find Largest Prime Factor
export function factor(num) {
for (let div = 2; div <= Math.sqrt(num); div++) {
if (num % div != 0) {
continue;
}
num = num / div;
div = 1;
}
return num;
}
// Merge Overlapping Intervals
export function mergeOverlap(intervals) {
intervals.sort(([minA], [minB]) => minA - minB);
for (let i = 0; i < intervals.length; i++) {
for (let j = i + 1; j < intervals.length; j++) {
const [min, max] = intervals[i];
const [laterMin, laterMax] = intervals[j];
if (laterMin <= max) {
const newMax = laterMax > max ? laterMax : max;
const newInterval = [min, newMax];
intervals[i] = newInterval;
intervals.splice(j, 1);
j = i;
}
}
}
return intervals;
}
// Minimum Path Sum in a Triangle
export function solveTriangleSum(arrayData) {
let triangle = arrayData;
let nextArray;
let previousArray = triangle[0];
for (let i = 1; i < triangle.length; i++) {
nextArray = [];
for (let j = 0; j < triangle[i].length; i++) {
if (j == 0) {
nextArray.push(previousArray[j] + triangle[i][j]);
} else if (j == triangle[i].length - 1) {
nextArray.push(Math.min(previousArray[j], previousArray[j - 1]) + triangle[i][j]);
} else {
nextArray.push(previousArray[j - 1] + triangle[i][j]);
}
}
previousArray = nextArray;
}
return Math.min(nextArray);
}
// Spiralize Matrix
export function spiral(arr, accum = []) {
if (arr.length === 0 || arr[0].length === 0) {
return accum;
}
accum = accum.concat(arr.shift());
if (arr.length === 0 || arr[0].length === 0) {
return accum;
}
accum = accum.concat(column(arr, arr[0].length - 1));
if (arr.length === 0 || arr[0].length === 0) {
return accum;
}
accum = accum.concat(arr.pop().reverse());
if (arr.length === 0 || arr[0].length === 0) {
return accum;
}
accum = accum.concat(column(arr, 0).reverse());
if (arr.length === 0 || arr[0].length === 0) {
return accum;
}
return spiral(arr, accum);
}
function column(arr, index) {
const res = [];
for (let i = 0; i < arr.length; i++) {
const elm = arr[i].splice(index, 1)[0];
if (elm) {
res.push(elm);
}
}
return res;
}
// Algorithmic Stock Trader I
// Algorithmic Stock Trader II
// Algorithmic Stock Trader III
// Algorithmic Stock Trader IV
export function maxProfit(arrayData) {
let i, j, k;
let maxTrades = arrayData[0];
let stockPrices = arrayData[1];
// WHY?
let tempStr = "[0";
for (i = 0; i < stockPrices.length; i++) {
tempStr += ",0";
}
tempStr += "]";
let tempArr = "[" + tempStr;
for (i = 0; i < maxTrades - 1; i++) {
tempArr += "," + tempStr;
}
tempArr += "]";
let highestProfit = JSON.parse(tempArr);
for (i = 0; i < maxTrades; i++) {
for (j = 0; j < stockPrices.length; j++) { // Buy / Start
for (k = j; k < stockPrices.length; k++) { // Sell / End
if (i > 0 && j > 0 && k > 0) {
highestProfit[i][k] = Math.max(highestProfit[i][k], highestProfit[i - 1][k], highestProfit[i][k - 1], highestProfit[i - 1][j - 1] + stockPrices[k] - stockPrices[j]);
} else if (i > 0 && j > 0) {
highestProfit[i][k] = Math.max(highestProfit[i][k], highestProfit[i - 1][k], highestProfit[i - 1][j - 1] + stockPrices[k] - stockPrices[j]);
} else if (i > 0 && k > 0) {
highestProfit[i][k] = Math.max(highestProfit[i][k], highestProfit[i - 1][k], highestProfit[i][k - 1], stockPrices[k] - stockPrices[j]);
} else if (j > 0 && k > 0) {
highestProfit[i][k] = Math.max(highestProfit[i][k], highestProfit[i][k - 1], stockPrices[k] - stockPrices[j]);
} else {
highestProfit[i][k] = Math.max(highestProfit[i][k], stockPrices[k] - stockPrices[j]);
}
}
}
}
return highestProfit[maxTrades - 1][stockPrices.length - 1];
}
// Unique Paths in a Grid I
// Unique Paths in a Grid II
export function uniquePathsI(grid) {
const rightMoves = grid[0] - 1;
const downMoves = grid[1] - 1;
return Math.round(factorialDivision(rightMoves + downMoves, rightMoves) / (factorial(downMoves)));
}
function factorial(n) {
return factorialDivision(n, 1);
}
function factorialDivision(n, d) {
if (n == 0 || n == 1 || n == d)
return 1;
return factorialDivision(n - 1, d) * n;
}
export function uniquePathsII(grid, ignoreFirst = false, ignoreLast = false) {
const rightMoves = grid[0].length - 1;
const downMoves = grid.length - 1;
let totalPossiblePaths = Math.round(factorialDivision(rightMoves + downMoves, rightMoves) / (factorial(downMoves)));
for (let i = 0; i < grid.length; i++) {
for (let j = 0; j < grid[i].length; j++) {
if (grid[i][j] == 1 && (!ignoreFirst || (i != 0 || j != 0))&& (!ignoreLast || (i != grid.length - 1 || j != grid[i].length - 1))) {
const newArray = [];
for (let k = i; k < grid.length; k++) {
newArray.push(grid[k].slice(j, grid[i].length));
}
let removedPaths = uniquePathsII(newArray, true, ignoreLast);
removedPaths *= uniquePathsI([i+1, j+1]);
totalPossiblePaths -= removedPaths;
}
}
}
return totalPossiblePaths;
}
@VaporGame
Copy link

If you are getting a fail on GenerateIPS then
replace return ips; with return ips.toString();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment