Files
bitburner-src/src/CodingContract/contracts/TotalWaysToSum.ts

93 lines
3.1 KiB
TypeScript

import { getRandomIntInclusive } from "../../utils/helpers/getRandomIntInclusive";
import { CodingContractTypes } from "../ContractTypes";
import { CodingContractName } from "@enums";
export const totalWaysToSum: Pick<
CodingContractTypes,
CodingContractName.TotalWaysToSum | CodingContractName.TotalWaysToSumII
> = {
[CodingContractName.TotalWaysToSum]: {
desc: (n: number): string => {
return [
"It is possible write four as a sum in exactly four different ways:\n\n",
" 3 + 1\n",
" 2 + 2\n",
" 2 + 1 + 1\n",
" 1 + 1 + 1 + 1\n\n",
`How many different distinct ways can the number ${n} be written as a sum of at least`,
"two positive integers?",
].join(" ");
},
difficulty: 1,
generate: (): number => {
return getRandomIntInclusive(8, 100);
},
getAnswer: (data) => {
if (typeof data !== "number") throw new Error("solver expected number");
const ways: number[] = [1];
ways.length = data + 1;
ways.fill(0, 1);
for (let i = 1; i < data; ++i) {
for (let j: number = i; j <= data; ++j) {
ways[j] += ways[j - i];
}
}
return ways[data];
},
solver: (data, answer) => {
return totalWaysToSum[CodingContractName.TotalWaysToSum].getAnswer(data) === answer;
},
convertAnswer: (ans) => parseInt(ans, 10),
validateAnswer: (ans): ans is number => typeof ans === "number",
},
[CodingContractName.TotalWaysToSumII]: {
desc: (data: [number, number[]]): string => {
const n: number = data[0];
const s: number[] = data[1];
return [
`How many different distinct ways can the number ${n} be written`,
"as a sum of integers contained in the set:\n\n",
`[${s}]?\n\n`,
"You may use each integer in the set zero or more times.",
].join(" ");
},
difficulty: 2,
generate: (): [number, number[]] => {
const n: number = getRandomIntInclusive(12, 200);
const maxLen: number = getRandomIntInclusive(8, 12);
const s: number[] = [];
// Bias towards small numbers is intentional to have much bigger answers in general
// to force people better optimize their solutions
for (let i = 1; i <= n; i++) {
if (s.length == maxLen) {
break;
}
if (Math.random() < 0.6 || n - i < maxLen - s.length) {
s.push(i);
}
}
return [n, s];
},
getAnswer: (data) => {
// https://www.geeksforgeeks.org/coin-change-dp-7/?ref=lbp
const n = data[0];
const s = data[1];
const ways: number[] = [1];
ways.length = n + 1;
ways.fill(0, 1);
for (let i = 0; i < s.length; i++) {
for (let j = s[i]; j <= n; j++) {
ways[j] += ways[j - s[i]];
}
}
return ways[n];
},
solver: (data, answer) => {
return totalWaysToSum[CodingContractName.TotalWaysToSumII].getAnswer(data) === answer;
},
convertAnswer: (ans) => parseInt(ans, 10),
validateAnswer: (ans): ans is number => typeof ans === "number",
},
};