Skip to content

Instantly share code, notes, and snippets.

@chasingmaxwell
Last active July 22, 2020 14:43
Show Gist options
  • Save chasingmaxwell/8211c12d669fd237852d1efedcadf5b7 to your computer and use it in GitHub Desktop.
Save chasingmaxwell/8211c12d669fd237852d1efedcadf5b7 to your computer and use it in GitHub Desktop.
Various ways to add up matching integers in a string.
/**
* Add each integer in a string which matches the next integer in the string.
*
* @param {string} input A string of integers to add up.
* @param {boolean} circular Indicates whether we should wrap around to the
* beginning of the input string when evaluating the last integer.
*/
function addEmUpNext(input, circular = false) {
let res = 0;
for (let i = 0; i < input.length; i++) {
// We don't need to keep track of the `prev` integer like I was doing
// before. Looking forward to the next integer is straightforward.
const target =
circular && i + 1 > input.length - 1 ? input[0] : input[i + 1];
if (input[i] === target) {
res = res + parseInt(input[i], 10);
}
}
return res;
}
/**
* Add each integer in a string which matches its corresponding integer in the
* second half of the string. If an odd number of characters is provided, the
* middle character is ignored.
*
* @param {string} input A string of integers to add up.
* @param {boolean} circular Indicates whether we should wrap around to the
* beginning of the input string when evaluating the integers in the second half
* of the string.
*/
function addEmUpHalf(input, circular = false) {
res = 0;
// Previously we were creating this array twice. That might become an issue if
// the string was extremely long.
const arr = [...input];
const half = Math.floor(input.length / 2);
const first = arr.slice(0, half);
// Using `-half` assures we can handle input with an odd number of integers by
// ignoring the integer in the center.
const second = arr.slice(-half);
for (let i = 0; i < first.length; i++) {
if (first[i] === second[i]) {
res = res + parseInt(first[i], 10);
}
}
// Since comparing the second half with the first half is the same as
// comparing the first half with the second half, we know that performing a
// circular operation will simply double the value.
if (circular) {
res = res * 2;
}
return res;
}
/**
* What follows is a very crude test suite to verify the above functions
* against some example cases.
*/
const casesForNext = [
["1212", 0],
["1122", 3],
["91234489", 4],
["12312", 0],
["1111", 3],
];
const casesForNextCircular = [
["1212", 0],
["1122", 3],
["91234489", 13],
["12312", 0],
["1111", 4],
];
const casesForHalf = [
["1212", 3],
["1122", 0],
["91234489", 0],
["12312", 3],
["1111", 2],
];
const casesForHalfCircular = [
["1212", 6],
["1122", 0],
["91234489", 0],
["12312", 6],
["1111", 4],
];
function testCases(cases, fn, additionalArgs = []) {
const caseResult = [0, 0];
for (const [input, expectedOutput] of cases) {
const res = fn(input, ...additionalArgs);
const pass = res === expectedOutput;
if (pass) {
caseResult[0] = caseResult[0] + 1;
} else {
caseResult[1] = caseResult[1] + 1;
}
console[pass ? "log" : "error"](
`${fn.name}("${input}"${
additionalArgs.length > 0 ? `, ${additionalArgs.join(", ")}` : ""
})\nres: ${res}\nexpected: ${expectedOutput}\n${
pass ? "PASS" : "FAIL"
}\n\n`
);
}
return caseResult;
}
const testSuite = [
testCases(casesForNext, addEmUpNext),
testCases(casesForNextCircular, addEmUpNext, [true]),
testCases(casesForHalf, addEmUpHalf),
testCases(casesForHalfCircular, addEmUpHalf, [true]),
];
let suitePasses = 0;
let suiteFails = 0;
for ([passes, fails] of testSuite) {
suitePasses = suitePasses + passes;
suiteFails = suiteFails + fails;
}
console.log("TOTAL PASSED:", suitePasses);
console.log("TOTAL FAILED:", suiteFails);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment